From 436b66be82167055844dfa39ed452ab07a22f279 Mon Sep 17 00:00:00 2001
From: Emux <devemux86@gmail.com>
Date: Thu, 21 Jul 2016 20:22:22 +0300
Subject: [PATCH] vtm-app: revive / update with latest VTM, closes #90

---
 settings.gradle                               |   1 +
 vtm-app/AndroidManifest.xml                   |  65 ++
 vtm-app/COPYING                               | 674 ++++++++++++++++++
 vtm-app/COPYING.LESSER                        | 165 +++++
 vtm-app/assets/globe2.png                     | Bin 0 -> 6256 bytes
 vtm-app/assets/info.xml                       |  25 +
 vtm-app/build.gradle                          |  47 ++
 vtm-app/project.properties                    |  14 +
 vtm-app/res/anim/slide_left.xml               |   9 +
 vtm-app/res/anim/slide_left2.xml              |   9 +
 vtm-app/res/anim/slide_right.xml              |   9 +
 vtm-app/res/anim/slide_right2.xml             |   9 +
 .../res/drawable-hdpi/ic_action_search.png    | Bin 0 -> 3120 bytes
 vtm-app/res/drawable-hdpi/ic_launcher.png     | Bin 0 -> 3437 bytes
 vtm-app/res/drawable-hdpi/ic_layers.png       | Bin 0 -> 3340 bytes
 .../res/drawable-mdpi/bonuspack_bubble.9.png  | Bin 0 -> 741 bytes
 vtm-app/res/drawable-mdpi/btn_snap_normal.png | Bin 0 -> 1755 bytes
 .../res/drawable-mdpi/btn_snap_pressed.png    | Bin 0 -> 1897 bytes
 .../res/drawable-mdpi/btn_snap_selected.png   | Bin 0 -> 1648 bytes
 vtm-app/res/drawable-mdpi/car.png             | Bin 0 -> 540 bytes
 vtm-app/res/drawable-mdpi/delete.png          | Bin 0 -> 2645 bytes
 vtm-app/res/drawable-mdpi/delete_pressed.png  | Bin 0 -> 2574 bytes
 .../res/drawable-mdpi/file_picker_back.png    | Bin 0 -> 1951 bytes
 .../res/drawable-mdpi/file_picker_file.png    | Bin 0 -> 1024 bytes
 .../res/drawable-mdpi/file_picker_folder.png  | Bin 0 -> 1460 bytes
 .../res/drawable-mdpi/ic_action_search.png    | Bin 0 -> 3030 bytes
 vtm-app/res/drawable-mdpi/ic_continue.png     | Bin 0 -> 414 bytes
 vtm-app/res/drawable-mdpi/ic_empty.png        | Bin 0 -> 240 bytes
 vtm-app/res/drawable-mdpi/ic_launcher.png     | Bin 0 -> 1396 bytes
 vtm-app/res/drawable-mdpi/ic_layers.png       | Bin 0 -> 1833 bytes
 .../res/drawable-mdpi/ic_menu_mylocation.png  | Bin 0 -> 1409 bytes
 vtm-app/res/drawable-mdpi/ic_menu_options.png | Bin 0 -> 1339 bytes
 vtm-app/res/drawable-mdpi/info.png            | Bin 0 -> 1333 bytes
 vtm-app/res/drawable-mdpi/info_window.9.png   | Bin 0 -> 416 bytes
 vtm-app/res/drawable-mdpi/moreinfo_arrow.png  | Bin 0 -> 1500 bytes
 .../drawable-mdpi/moreinfo_arrow_pressed.png  | Bin 0 -> 1582 bytes
 vtm-app/res/drawable-mdpi/no.png              | Bin 0 -> 443 bytes
 vtm-app/res/drawable-mdpi/plane.png           | Bin 0 -> 407 bytes
 vtm-app/res/drawable-mdpi/time.png            | Bin 0 -> 597 bytes
 vtm-app/res/drawable-mdpi/yes.png             | Bin 0 -> 377 bytes
 vtm-app/res/drawable-nodpi/direction.png      | Bin 0 -> 1826 bytes
 vtm-app/res/drawable-nodpi/ic_launcher.png    | Bin 0 -> 3907 bytes
 .../res/drawable-nodpi/marker_departure.png   | Bin 0 -> 1413 bytes
 .../res/drawable-nodpi/marker_destination.png | Bin 0 -> 1160 bytes
 vtm-app/res/drawable-nodpi/marker_node.png    | Bin 0 -> 611 bytes
 .../res/drawable-nodpi/marker_poi_default.png | Bin 0 -> 610 bytes
 .../res/drawable-nodpi/marker_poi_flickr.png  | Bin 0 -> 490 bytes
 .../drawable-nodpi/marker_poi_picasa_24.png   | Bin 0 -> 2295 bytes
 .../marker_poi_wikipedia_16.png               | Bin 0 -> 1474 bytes
 .../marker_poi_wikipedia_32.png               | Bin 0 -> 2117 bytes
 vtm-app/res/drawable-nodpi/marker_via.png     | Bin 0 -> 1119 bytes
 vtm-app/res/drawable-nodpi/pin.png            | Bin 0 -> 1725 bytes
 .../res/drawable-xhdpi/ic_action_search.png   | Bin 0 -> 3199 bytes
 vtm-app/res/drawable-xhdpi/ic_launcher.png    | Bin 0 -> 4591 bytes
 vtm-app/res/drawable-xhdpi/ic_layers.png      | Bin 0 -> 4940 bytes
 vtm-app/res/drawable/arrow.png                | Bin 0 -> 10033 bytes
 vtm-app/res/drawable/bkg_compass.png          | Bin 0 -> 40821 bytes
 vtm-app/res/drawable/btn_delete.xml           |   6 +
 vtm-app/res/drawable/btn_moreinfo.xml         |   6 +
 vtm-app/res/drawable/compass.png              | Bin 0 -> 1826 bytes
 vtm-app/res/drawable/globe2.png               | Bin 0 -> 6256 bytes
 vtm-app/res/drawable/person.png               | Bin 0 -> 1531 bytes
 vtm-app/res/layout/activity_file_picker.xml   |   9 +
 vtm-app/res/layout/activity_tilemap.xml       | 126 ++++
 vtm-app/res/layout/bonuspack_bubble.xml       |  67 ++
 .../res/layout/dialog_enter_coordinates.xml   |  59 ++
 vtm-app/res/layout/dialog_info_map_file.xml   | 155 ++++
 vtm-app/res/layout/item_layout.xml            |  34 +
 vtm-app/res/layout/items_list.xml             |  80 +++
 vtm-app/res/layout/itinerary_bubble.xml       |  61 ++
 vtm-app/res/layout/seek_bar_preference.xml    |  61 ++
 vtm-app/res/menu/map_menu.xml                 |  22 +
 vtm-app/res/menu/options_menu.xml             | 106 +++
 vtm-app/res/menu/poi_menu.xml                 |  10 +
 vtm-app/res/values-v11/styles.xml             |   5 +
 vtm-app/res/values-v14/styles.xml             |   5 +
 vtm-app/res/values/poi_tags.xml               | 102 +++
 vtm-app/res/values/route.xml                  |   4 +
 vtm-app/res/values/settings.xml               | 115 +++
 vtm-app/res/values/strings.xml                |  68 ++
 vtm-app/res/values/styles.xml                 |   5 +
 vtm-app/res/xml/preferences.xml               | 126 ++++
 vtm-app/src/android-logger.properties         |   1 +
 vtm-app/src/org/oscim/app/App.java            |  70 ++
 .../src/org/oscim/app/ConnectionHandler.java  |  31 +
 vtm-app/src/org/oscim/app/FileUtils.java      |  63 ++
 vtm-app/src/org/oscim/app/InfoView.java       |  47 ++
 vtm-app/src/org/oscim/app/MapActivity.java    | 125 ++++
 vtm-app/src/org/oscim/app/MapLayers.java      | 189 +++++
 vtm-app/src/org/oscim/app/POIActivity.java    | 309 ++++++++
 vtm-app/src/org/oscim/app/POISearch.java      | 320 +++++++++
 vtm-app/src/org/oscim/app/RouteSearch.java    | 452 ++++++++++++
 vtm-app/src/org/oscim/app/TileMap.java        | 518 ++++++++++++++
 .../app/filefilter/FilterByFileExtension.java |  47 ++
 .../oscim/app/filefilter/ValidFileFilter.java |  29 +
 .../oscim/app/filefilter/ValidMapFile.java    |  42 ++
 .../app/filefilter/ValidRenderTheme.java      |  72 ++
 .../org/oscim/app/filepicker/FilePicker.java  | 262 +++++++
 .../app/filepicker/FilePickerIconAdapter.java | 114 +++
 .../src/org/oscim/app/location/Compass.java   | 392 ++++++++++
 .../oscim/app/location/LocationDialog.java    | 120 ++++
 .../oscim/app/location/LocationHandler.java   | 236 ++++++
 .../oscim/app/location/LocationOverlay.java   | 331 +++++++++
 .../app/preferences/CacheSizePreference.java  | 219 ++++++
 .../app/preferences/EditPreferences.java      |  68 ++
 .../app/preferences/SeekBarPreference.java    | 153 ++++
 .../oscim/overlay/DistanceTouchOverlay.java   | 182 +++++
 .../osmdroid/location/FlickrPOIProvider.java  | 163 +++++
 .../osmdroid/location/FourSquareProvider.java | 186 +++++
 .../location/GeoNamesPOIProvider.java         | 215 ++++++
 .../osmdroid/location/GeocoderNominatim.java  | 208 ++++++
 .../location/NominatimPOIProvider.java        | 192 +++++
 .../location/OverpassPOIProvider.java         |  67 ++
 vtm-app/src/org/osmdroid/location/POI.java    | 205 ++++++
 .../org/osmdroid/location/POIProvider.java    |  10 +
 .../osmdroid/location/PicasaPOIProvider.java  | 161 +++++
 .../osmdroid/overlays/DefaultInfoWindow.java  |  99 +++
 .../osmdroid/overlays/ExtendedMarkerItem.java | 123 ++++
 .../src/org/osmdroid/overlays/InfoWindow.java | 135 ++++
 .../overlays/ItemizedOverlayWithBubble.java   | 195 +++++
 .../osmdroid/overlays/MapEventsReceiver.java  |  34 +
 vtm-app/src/org/osmdroid/routing/Route.java   | 255 +++++++
 .../src/org/osmdroid/routing/RouteLeg.java    |  85 +++
 .../src/org/osmdroid/routing/RouteNode.java   |  79 ++
 .../org/osmdroid/routing/RouteProvider.java   |  67 ++
 .../routing/provider/GoogleRouteProvider.java | 235 ++++++
 .../provider/MapQuestRouteProvider.java       | 289 ++++++++
 .../routing/provider/OSRMRouteProvider.java   | 294 ++++++++
 .../org/osmdroid/utils/BonusPackHelper.java   | 112 +++
 .../osmdroid/utils/DouglasPeuckerReducer.java | 141 ++++
 .../org/osmdroid/utils/HttpConnection.java    | 119 ++++
 .../src/org/osmdroid/utils/MathConstants.java |  22 +
 .../org/osmdroid/utils/PolylineEncoder.java   |  94 +++
 133 files changed, 10436 insertions(+)
 create mode 100644 vtm-app/AndroidManifest.xml
 create mode 100644 vtm-app/COPYING
 create mode 100644 vtm-app/COPYING.LESSER
 create mode 100644 vtm-app/assets/globe2.png
 create mode 100644 vtm-app/assets/info.xml
 create mode 100644 vtm-app/build.gradle
 create mode 100644 vtm-app/project.properties
 create mode 100644 vtm-app/res/anim/slide_left.xml
 create mode 100644 vtm-app/res/anim/slide_left2.xml
 create mode 100644 vtm-app/res/anim/slide_right.xml
 create mode 100644 vtm-app/res/anim/slide_right2.xml
 create mode 100644 vtm-app/res/drawable-hdpi/ic_action_search.png
 create mode 100644 vtm-app/res/drawable-hdpi/ic_launcher.png
 create mode 100644 vtm-app/res/drawable-hdpi/ic_layers.png
 create mode 100644 vtm-app/res/drawable-mdpi/bonuspack_bubble.9.png
 create mode 100644 vtm-app/res/drawable-mdpi/btn_snap_normal.png
 create mode 100644 vtm-app/res/drawable-mdpi/btn_snap_pressed.png
 create mode 100644 vtm-app/res/drawable-mdpi/btn_snap_selected.png
 create mode 100644 vtm-app/res/drawable-mdpi/car.png
 create mode 100644 vtm-app/res/drawable-mdpi/delete.png
 create mode 100644 vtm-app/res/drawable-mdpi/delete_pressed.png
 create mode 100644 vtm-app/res/drawable-mdpi/file_picker_back.png
 create mode 100644 vtm-app/res/drawable-mdpi/file_picker_file.png
 create mode 100644 vtm-app/res/drawable-mdpi/file_picker_folder.png
 create mode 100644 vtm-app/res/drawable-mdpi/ic_action_search.png
 create mode 100644 vtm-app/res/drawable-mdpi/ic_continue.png
 create mode 100644 vtm-app/res/drawable-mdpi/ic_empty.png
 create mode 100644 vtm-app/res/drawable-mdpi/ic_launcher.png
 create mode 100644 vtm-app/res/drawable-mdpi/ic_layers.png
 create mode 100644 vtm-app/res/drawable-mdpi/ic_menu_mylocation.png
 create mode 100644 vtm-app/res/drawable-mdpi/ic_menu_options.png
 create mode 100644 vtm-app/res/drawable-mdpi/info.png
 create mode 100644 vtm-app/res/drawable-mdpi/info_window.9.png
 create mode 100644 vtm-app/res/drawable-mdpi/moreinfo_arrow.png
 create mode 100644 vtm-app/res/drawable-mdpi/moreinfo_arrow_pressed.png
 create mode 100644 vtm-app/res/drawable-mdpi/no.png
 create mode 100644 vtm-app/res/drawable-mdpi/plane.png
 create mode 100644 vtm-app/res/drawable-mdpi/time.png
 create mode 100644 vtm-app/res/drawable-mdpi/yes.png
 create mode 100644 vtm-app/res/drawable-nodpi/direction.png
 create mode 100644 vtm-app/res/drawable-nodpi/ic_launcher.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_departure.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_destination.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_node.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_poi_default.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_poi_flickr.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_poi_picasa_24.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_poi_wikipedia_16.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_poi_wikipedia_32.png
 create mode 100644 vtm-app/res/drawable-nodpi/marker_via.png
 create mode 100644 vtm-app/res/drawable-nodpi/pin.png
 create mode 100644 vtm-app/res/drawable-xhdpi/ic_action_search.png
 create mode 100644 vtm-app/res/drawable-xhdpi/ic_launcher.png
 create mode 100644 vtm-app/res/drawable-xhdpi/ic_layers.png
 create mode 100644 vtm-app/res/drawable/arrow.png
 create mode 100644 vtm-app/res/drawable/bkg_compass.png
 create mode 100644 vtm-app/res/drawable/btn_delete.xml
 create mode 100644 vtm-app/res/drawable/btn_moreinfo.xml
 create mode 100644 vtm-app/res/drawable/compass.png
 create mode 100644 vtm-app/res/drawable/globe2.png
 create mode 100644 vtm-app/res/drawable/person.png
 create mode 100644 vtm-app/res/layout/activity_file_picker.xml
 create mode 100644 vtm-app/res/layout/activity_tilemap.xml
 create mode 100644 vtm-app/res/layout/bonuspack_bubble.xml
 create mode 100644 vtm-app/res/layout/dialog_enter_coordinates.xml
 create mode 100644 vtm-app/res/layout/dialog_info_map_file.xml
 create mode 100644 vtm-app/res/layout/item_layout.xml
 create mode 100644 vtm-app/res/layout/items_list.xml
 create mode 100644 vtm-app/res/layout/itinerary_bubble.xml
 create mode 100644 vtm-app/res/layout/seek_bar_preference.xml
 create mode 100644 vtm-app/res/menu/map_menu.xml
 create mode 100644 vtm-app/res/menu/options_menu.xml
 create mode 100644 vtm-app/res/menu/poi_menu.xml
 create mode 100644 vtm-app/res/values-v11/styles.xml
 create mode 100644 vtm-app/res/values-v14/styles.xml
 create mode 100644 vtm-app/res/values/poi_tags.xml
 create mode 100644 vtm-app/res/values/route.xml
 create mode 100644 vtm-app/res/values/settings.xml
 create mode 100755 vtm-app/res/values/strings.xml
 create mode 100644 vtm-app/res/values/styles.xml
 create mode 100644 vtm-app/res/xml/preferences.xml
 create mode 100644 vtm-app/src/android-logger.properties
 create mode 100644 vtm-app/src/org/oscim/app/App.java
 create mode 100644 vtm-app/src/org/oscim/app/ConnectionHandler.java
 create mode 100644 vtm-app/src/org/oscim/app/FileUtils.java
 create mode 100644 vtm-app/src/org/oscim/app/InfoView.java
 create mode 100644 vtm-app/src/org/oscim/app/MapActivity.java
 create mode 100644 vtm-app/src/org/oscim/app/MapLayers.java
 create mode 100644 vtm-app/src/org/oscim/app/POIActivity.java
 create mode 100644 vtm-app/src/org/oscim/app/POISearch.java
 create mode 100644 vtm-app/src/org/oscim/app/RouteSearch.java
 create mode 100755 vtm-app/src/org/oscim/app/TileMap.java
 create mode 100644 vtm-app/src/org/oscim/app/filefilter/FilterByFileExtension.java
 create mode 100644 vtm-app/src/org/oscim/app/filefilter/ValidFileFilter.java
 create mode 100644 vtm-app/src/org/oscim/app/filefilter/ValidMapFile.java
 create mode 100644 vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java
 create mode 100755 vtm-app/src/org/oscim/app/filepicker/FilePicker.java
 create mode 100755 vtm-app/src/org/oscim/app/filepicker/FilePickerIconAdapter.java
 create mode 100644 vtm-app/src/org/oscim/app/location/Compass.java
 create mode 100644 vtm-app/src/org/oscim/app/location/LocationDialog.java
 create mode 100644 vtm-app/src/org/oscim/app/location/LocationHandler.java
 create mode 100644 vtm-app/src/org/oscim/app/location/LocationOverlay.java
 create mode 100644 vtm-app/src/org/oscim/app/preferences/CacheSizePreference.java
 create mode 100644 vtm-app/src/org/oscim/app/preferences/EditPreferences.java
 create mode 100644 vtm-app/src/org/oscim/app/preferences/SeekBarPreference.java
 create mode 100644 vtm-app/src/org/oscim/overlay/DistanceTouchOverlay.java
 create mode 100644 vtm-app/src/org/osmdroid/location/FlickrPOIProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/location/FourSquareProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/location/GeoNamesPOIProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/location/GeocoderNominatim.java
 create mode 100644 vtm-app/src/org/osmdroid/location/NominatimPOIProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/location/OverpassPOIProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/location/POI.java
 create mode 100644 vtm-app/src/org/osmdroid/location/POIProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/location/PicasaPOIProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/overlays/DefaultInfoWindow.java
 create mode 100644 vtm-app/src/org/osmdroid/overlays/ExtendedMarkerItem.java
 create mode 100644 vtm-app/src/org/osmdroid/overlays/InfoWindow.java
 create mode 100644 vtm-app/src/org/osmdroid/overlays/ItemizedOverlayWithBubble.java
 create mode 100644 vtm-app/src/org/osmdroid/overlays/MapEventsReceiver.java
 create mode 100644 vtm-app/src/org/osmdroid/routing/Route.java
 create mode 100644 vtm-app/src/org/osmdroid/routing/RouteLeg.java
 create mode 100644 vtm-app/src/org/osmdroid/routing/RouteNode.java
 create mode 100644 vtm-app/src/org/osmdroid/routing/RouteProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/routing/provider/GoogleRouteProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/routing/provider/MapQuestRouteProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/routing/provider/OSRMRouteProvider.java
 create mode 100644 vtm-app/src/org/osmdroid/utils/BonusPackHelper.java
 create mode 100644 vtm-app/src/org/osmdroid/utils/DouglasPeuckerReducer.java
 create mode 100644 vtm-app/src/org/osmdroid/utils/HttpConnection.java
 create mode 100644 vtm-app/src/org/osmdroid/utils/MathConstants.java
 create mode 100644 vtm-app/src/org/osmdroid/utils/PolylineEncoder.java

diff --git a/settings.gradle b/settings.gradle
index 0237e353..6babee72 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -16,3 +16,4 @@ include ':vtm-android-gdx'
 include ':vtm-jeo'
 include ':vtm-playground'
 include ':vtm-ios'
+include ':vtm-app'
diff --git a/vtm-app/AndroidManifest.xml b/vtm-app/AndroidManifest.xml
new file mode 100644
index 00000000..3c4c22ad
--- /dev/null
+++ b/vtm-app/AndroidManifest.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.oscim.app"
+    android:installLocation="auto"
+    android:versionCode="11"
+    android:versionName="0.6.0">
+
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <uses-sdk
+        android:minSdkVersion="10"
+        android:targetSdkVersion="22" />
+
+    <application
+        android:name=".App"
+        android:allowBackup="true"
+        android:icon="@drawable/globe2"
+        android:label="@string/application_name">
+
+        <!-- android:theme="@style/Theme.TileMap" -->
+        <activity
+            android:name=".TileMap"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:launchMode="singleTask">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="geo" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".preferences.EditPreferences"
+            android:configChanges="keyboardHidden|orientation|screenSize" />
+        <activity
+            android:name=".filepicker.FilePicker"
+            android:configChanges="keyboardHidden|orientation|screenSize" />
+        <activity
+            android:name=".InfoView"
+            android:configChanges="keyboardHidden|orientation|screenSize" />
+        <activity
+            android:name=".POIActivity"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden" />
+
+        <!-- <receiver
+             android:name=".ConnectionHandler"
+             android:label="NetworkConnection" >
+             <intent-filter>
+                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+             </intent-filter>
+         </receiver> -->
+    </application>
+
+</manifest>
diff --git a/vtm-app/COPYING b/vtm-app/COPYING
new file mode 100644
index 00000000..94a9ed02
--- /dev/null
+++ b/vtm-app/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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, either version 3 of the License, or
+    (at your option) any later version.
+
+    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/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/vtm-app/COPYING.LESSER b/vtm-app/COPYING.LESSER
new file mode 100644
index 00000000..65c5ca88
--- /dev/null
+++ b/vtm-app/COPYING.LESSER
@@ -0,0 +1,165 @@
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/vtm-app/assets/globe2.png b/vtm-app/assets/globe2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d788024b03350e799951cc58809c36ee88b905c
GIT binary patch
literal 6256
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
aJo`V`RkX|Juz#xn0000<MNUMnLSTaVoY_kN

literal 0
HcmV?d00001

diff --git a/vtm-app/assets/info.xml b/vtm-app/assets/info.xml
new file mode 100644
index 00000000..52b9a25b
--- /dev/null
+++ b/vtm-app/assets/info.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>About this software</title>
+		<meta http-equiv="Content-Style-Type" content="text/css" />
+	</head>
+	<body style="padding: 0.5em;">
+		<p style="text-align: center;"><img src="file:///android_asset/globe2.png" style="width: 72px; height: 72px;" /><br />Version 0.6.0</p>
+		<p> 
+		    <li><a href="http://www.opensciencemap.org">OpenScienceMap</a> is 
+		        distributed under the <a href="http://www.gnu.org/licenses/lgpl.html">LGPL3</a>. 
+		    Please report any  bugs, problems or feature requests via our 
+		    <a href="https://github.com/opensciencemap/vtm/issues">issue tracker</a></li></p>
+		<p></p>
+		<p></p>    		    
+		
+		<p> <li>Map data for 'OpenScienceMap' source © <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, 
+		 licensed under the Open Data Commons Open Database License (ODbL).</li></p>
+		
+        <p> <li> This software contains fragments of <a href="https://code.google.com/p/mapsforge">mapsforge</a> 
+        library and <a href="http://code.google.com/p/osmdroid">osmdroid</a>.</li></p>
+        
+	</body>
+</html>
\ No newline at end of file
diff --git a/vtm-app/build.gradle b/vtm-app/build.gradle
new file mode 100644
index 00000000..6924ba19
--- /dev/null
+++ b/vtm-app/build.gradle
@@ -0,0 +1,47 @@
+apply plugin: 'com.android.application'
+
+dependencies {
+    compile project(':vtm-android')
+    compile project(':vtm-themes')
+    compile project(':vtm-extras')
+    compile 'com.noveogroup.android:android-logger:1.3.6'
+    compile 'com.squareup.okhttp:okhttp:2.6.0'
+}
+
+android {
+    compileSdkVersion androidCompileSdk()
+    buildToolsVersion "$androidBuildVersionTools"
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+
+    defaultConfig {
+        versionCode versionCode()
+        versionName versionName()
+        minSdkVersion androidMinSdk()
+    }
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest.xml'
+            java.srcDirs = ['src']
+            resources.srcDirs = ['src', 'assets']
+            res.srcDirs = ['res']
+            assets.srcDirs = ['assets']
+            file("${rootDir}/vtm-android/natives").eachDir() { dir ->
+                jniLibs.srcDirs += "${dir.path}/lib"
+            }
+        }
+        debug.setRoot('build-types/debug')
+        release.setRoot('build-types/release')
+    }
+
+    lintOptions { abortOnError false }
+
+    packagingOptions {
+        exclude 'META-INF/LICENSE'
+        exclude 'META-INF/NOTICE'
+    }
+}
diff --git a/vtm-app/project.properties b/vtm-app/project.properties
new file mode 100644
index 00000000..916037e3
--- /dev/null
+++ b/vtm-app/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-23
diff --git a/vtm-app/res/anim/slide_left.xml b/vtm-app/res/anim/slide_left.xml
new file mode 100644
index 00000000..315ba385
--- /dev/null
+++ b/vtm-app/res/anim/slide_left.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator">
+    <translate
+        android:fromXDelta="-100%p"
+        android:toXDelta="0"
+        android:duration="150" />
+</set>
\ No newline at end of file
diff --git a/vtm-app/res/anim/slide_left2.xml b/vtm-app/res/anim/slide_left2.xml
new file mode 100644
index 00000000..1a876727
--- /dev/null
+++ b/vtm-app/res/anim/slide_left2.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator">
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="-100%p"
+        android:duration="150" />
+</set>
\ No newline at end of file
diff --git a/vtm-app/res/anim/slide_right.xml b/vtm-app/res/anim/slide_right.xml
new file mode 100644
index 00000000..bf46b652
--- /dev/null
+++ b/vtm-app/res/anim/slide_right.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator">
+    <translate
+        android:fromXDelta="100%p"
+        android:toXDelta="0"
+        android:duration="150" />
+</set>
\ No newline at end of file
diff --git a/vtm-app/res/anim/slide_right2.xml b/vtm-app/res/anim/slide_right2.xml
new file mode 100644
index 00000000..8590c3b7
--- /dev/null
+++ b/vtm-app/res/anim/slide_right2.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator">
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="100%p"
+        android:duration="150" />
+</set>
\ No newline at end of file
diff --git a/vtm-app/res/drawable-hdpi/ic_action_search.png b/vtm-app/res/drawable-hdpi/ic_action_search.png
new file mode 100644
index 0000000000000000000000000000000000000000..67de12decbd60613f6716de113daae46dc7d6ff9
GIT binary patch
literal 3120
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-hdpi/ic_launcher.png b/vtm-app/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a0db8b6e1f15ee592bc80ce418ee04453eedf9a
GIT binary patch
literal 3437
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
P00000NkvXXu0mjfEMan-

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-hdpi/ic_layers.png b/vtm-app/res/drawable-hdpi/ic_layers.png
new file mode 100644
index 0000000000000000000000000000000000000000..a957474eda1c16dbbcf343331a2e276fd8841544
GIT binary patch
literal 3340
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
Lo_1)mM_>C7p+`1d

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/bonuspack_bubble.9.png b/vtm-app/res/drawable-mdpi/bonuspack_bubble.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..31a2ba65da355e3e5f6b5fb7d727fc67d7ca3708
GIT binary patch
literal 741
zcmV<B0vi2^P)<h;3K|Lk000e1NJLTq003A3002M;1^@s6o)ECY00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyu9
z79<_+#q4$f00L!6L_t(|+U=Y@j@nQZh2IY@f)u$=5h*JmlN}gVkXUR0kp?NsRQxnl
zlr)neRdx`I*$Pz#O+y+xAUBvuPUIiB(*Q!w1QD=@=gBz|vLzbs$ML!MJzHk%c+vXv
zl$3f+e0_Yoa}K4ao5BXP@B3eb5E7tMxD1HmVzKz1F~&B4nGiw>Aqv2Ax>l>z_FOy=
z7f^~4Kmfo14E?>|0Wcg4zz_ff@P7fAfFr%>0S-n)05Al=01Uv;>3}hw!NK_kj5`@{
zFaSdUd>-xIrhkf0>YPh|ZuSrnBLZJUM2;h3>tyJ}eAr<K2O}Z?7{ZvQz?cSQ91(=^
z0S-o!gZ4K$A|lSQJ)FWqgRqi2Lz4py%)$AK2sAlN5tt&NJqwLOGB?odvK!OT<g#2U
z!@0=dJVpdZ20vDlOMU^J<lqPAU~CCz>EJkyLn2~l&R{O3EU@FB_@w1>89(-wm~>_w
z$Kkf1_3@nwe|w|Rc-8CmK4_ZujB_sjvB*^vMZde<?)6|W_^ybPZ<HDtbX~8Srum}Z
z?_X+~R^$g>PDDge6#Z&8n^(i(@W*^U|Efw&QYFAa5Zq2Clb5z_f2&j~Zw`5f&<1X+
z)%s*vmg9MzrBY2w0Zu@^H4NiIN~!JR8w7#hZnv*3%W@Wrg{4|O$^qVm>^RQYFpSqy
zN-dcdL_}d2`khYav#M~F1)PLjE|)LXka?cq=0duzS8KJ}N7r@lJkPT|&$C_Ey{p&j
zm%6T3K`2GY)9G|Po6W{~g3I#+xl}4W7eesSX!H}YkVV6g(v(t~dHT(VIvAT2M>4zz
X(y%=X!_SJ600000NkvXXu0mjfB6C6-

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/btn_snap_normal.png b/vtm-app/res/drawable-mdpi/btn_snap_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..547ccb3f694931115d5201448363734896c51f69
GIT binary patch
literal 1755
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/btn_snap_pressed.png b/vtm-app/res/drawable-mdpi/btn_snap_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..065dac9316a13c8e0c1309b4e0f110413c5a17d8
GIT binary patch
literal 1897
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/btn_snap_selected.png b/vtm-app/res/drawable-mdpi/btn_snap_selected.png
new file mode 100644
index 0000000000000000000000000000000000000000..551e74fe2bf1f0af5e38a3d97c283e2c2b99820f
GIT binary patch
literal 1648
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/car.png b/vtm-app/res/drawable-mdpi/car.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ff280ae67413491984b51f83d6709c5db44ca9e
GIT binary patch
literal 540
zcmV+%0^|LOP)<h;3K|Lk000e1NJLTq001BW001Be0ssI2{21+{0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzzDYzuRCwC#md%lZKoEs>%R6MC8E6Jb
z1egJ4AQ>2fA!r7gffxZA0T=-q0sED0jpGcAh`Tr6ff}2h{_lsq-WOkdihdiV@pwF)
zPJQ3kg=v}|4u?<u2SJc!S=E5;cI$awck8Rw3M*w<Mp1+(^3dO6dc9ubzN3%jaw%cP
zaqLjbZg|@V!HV@f&)u5C;gA&f`~7<kxF8M|i$%*^+h{(5Qf=h?QlI*iH`EsD#}>_I
zGdUDRaXz14I=Ei1yWNf<PLkxk`Y?qplV;3h-dx?LvC6c7;<j&F)5zUR#Eawc$hvl3
z8WvkGZ%vn~uCVX28Bf_WVbwo?JvY1h=YU`awFSLgF0_QhWHK>G)BtKIbExg#T}Uo^
zL5-bkDj<a>Kz%(KYeVPW2}VeXm}sF%aR#CCQ&&)NAXk$OWyydVJ|0smdcs*oOJv=Q
zuL3uP=5!&!=`{1ivYfC>Mv6yua80pylSC}4P_QOEHc)&Lh9RQSXk_;a;byauRT98a
z^xszFIiJsYo=zthHQMF2HSNYc2Hy?irsIpIj~{)mjicZ6NsvsbjGM7>Pi0sIG^z9V
eZ(0ZZ3NQfO6co)_zipcU0000<MNUMnLSTY#$MKy2

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/delete.png b/vtm-app/res/drawable-mdpi/delete.png
new file mode 100644
index 0000000000000000000000000000000000000000..7fca7db24fb72925a899978d8c816587b9624269
GIT binary patch
literal 2645
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
D62Bqm

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/delete_pressed.png b/vtm-app/res/drawable-mdpi/delete_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc2d71f7bcd9ca98a71426c754cdeb3fa30fa995
GIT binary patch
literal 2574
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/file_picker_back.png b/vtm-app/res/drawable-mdpi/file_picker_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..671901539449fd2f4f4993acfdd4b85de89cf0bb
GIT binary patch
literal 1951
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/file_picker_file.png b/vtm-app/res/drawable-mdpi/file_picker_file.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0411244893b084e7ffe4aae7c28e679f3d75603
GIT binary patch
literal 1024
zcmV+b1poVqP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00001b5ch_0Itp)
z=>Px&x=BPqRA}DqS-WoAFcdu$ZOefa#i=bIaDrsYFLddazv$kzpO7iPkfCe-pj+qu
zMW&2_10w-aBrx<KZ-<HoMU%2*SwRO~zz`)d(mA~6KEwdM_10T&y|pk_XVUHM?dPMT
zqhC=Jg`Veuv44L?M37QKN(muE>A3Bh8tdo9HSgi!;m6(G-S;}!26ZN7S@!Mf>grP%
zh9DvU0OuS+2r$M#MDRRseNQ+2nwsk}B0>~JxVgFc3SfT(q?8~cyu7?XN(lh)eIHqt
zt$``8sG~Wyo!f{8K~P&6wF#()Gse~{tw7trSCMdPd5d>idq4-H2q;^vRuDooUUg+*
z7?u{IQv&Add!Dx;qix{z>-zJWc&rftwYn~OyuH04Ns>z7E?`82FbthZU~e&?%f|G=
zY&I+1cg28<1n0aI15JoD@_;EJW$*9r$g<2SAv0!73C(7+?qk3PT*ZJ80(qW0Gto8)
znK9If2lR*PFC`*Or&DJtZAwH>8ha-|M0k9B#M#+d3DEQN^E!yDvWW})>FMdmWuZ8Z
zF&GR=Y1H?9aL#wG#AboqyM&ZWIp^S<BTZ9`$K$o@4-XHm`FtB01yt1%o1FF@17^DP
zJP%J#Pe_tvLk3mZN4N9y^Ad?p2)L>-08AzmYc{Fd8!7p9O2E}{DL_)njg_|nsR~j>
zzEcUA{SN@VzP=(&(+znM5sr_KF`Z6prBHS3B#l;iU_PIhq+=44QkFDsYv!6tr<Div
z7*O>=2dB$P5vnR|datEEQ#&CbrNm;fz<fS0fm<vV)+|(~G6TTH#l=P{?W~YZCKC*Y
z!_xhelN0OLnQLsy(dNlcJis|e5Clk)1mp2|{o>_vi8M`XdB9f4R2|r*Bi*T)GXruo
z8g2bXu4=XQ80lO>wylyN2%LqiN?PW}(T8LqTMl0?msqV<8`3dBo2`Yi%gf7BHE!aK
z)&x{wM^WUIkX{$UFvP*ZK`C(aJa>}oL_)T1Rn4*OQs{L-pSx@3X-pu`bM7iGj4?z}
zWGz@G8CRF;Xek(gt?af{4+bDg)6}oCbEm$Y^^ISBrPY1cSbH7=Fa<DbOJE2f$g*tc
z+VZG#ZWb(awas3Lh&%uxfS|2}IDml=f^*I(j$@_(nWf*=ptacc9~AFzMIZx^2qAu6
zUtfQT<9I+stV+u*!4m-7-{1cRkQBex|KRWeM1?#3f^@6pt-z8OzZHNt0Dl0;wggnH
ujEb1xbzHlnWdH<#v>5l+TW`Jn=k^ydg}8-Qpwv|W0000<MNUMnLSTZDN7+08

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/file_picker_folder.png b/vtm-app/res/drawable-mdpi/file_picker_folder.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2c3f5fbd80d71cbef2fae3f670e983fca43526a
GIT binary patch
literal 1460
zcmV;l1xxygP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00001b5ch_0Itp)
z=>Px)Zb?KzRA}Dqn7@x4SrNxS)vtfdjQ4yxu|_LFLI64m5kW$Hk|W1R2u>tiWSp}J
znG+mf$pMx)>5w>yf54FmAaDi_5F8h*4s5h{_WA7d?0BcU-_IhLA3NTio!y<?5kgF9
zYTov|p5FRa)vNl}z*^R_mbI*9E&szJi#E5nw?F9hdOs17BloE)BJ$b_kWxzf`}@DV
zb?esle;vThn>Y8aUcGvGFc^?hnyRW!*F&ls8yoWA!Gm^hZ}08fw{JgQHGq84rm8k6
zrOUg!yHlfMjHoIx#@E1%@0UE!+1lDFo<D#7^&2;CJic@1&PoAfi#9_D?IcAGr_a1p
z0<hN7>2wV6?Nu9pVgy16P20BAbxn+M>h;4qn??X_+tTTDes%r&^><QA<}m1ajsR*A
z*}i-C?xz<Cpf$$O>-F&79}8mkOpFcFD_5@cHa9nau(h>CQ51*>B0`pB({-XE!qcZu
zxqtuuXTZ-d6hK|q^!t6BbJH_$iYN#`zu#wPXJ=F`#sDV98)Fa=j4@<cHhIQd7kUP~
z_l<~9mL)||V2mNp^XWgGT@N(Fn2~4mJf|$nu@;nNNmW(T=S}visv^&GVvHN}?D*b$
zA1)sO=N!&CthMZXS+d(VsOF%GqG%eeqnD1HKbzY!c~b;I1eipFgQ$R^@8ACZw|?~7
zI~l2%e7!1-0KWh}UkX470c$PJId)!N=Di<YWo+%iVSMcmMdy~}IiDT5&~GUGYzDmk
z@z0OsZ#z%^1pNNY0KE4NKvh+Q7|Be@SKsRK*GDfIm;O_=ML9z|l^MWad7~6T5s^nr
zr_gXXWH1=8zdxiXzD88#RTEZP+f_$VtO}#n2LT>01;AR{<ath~)4_*GMVFM6q)H~T
zBI8FDtFe(P&#*4?@cnl`TdE4Bl-j0gXxnzwoT>`v6LXXNqR5#*Op5i9s>sC0w6GE_
zj6jUB@!n6s(CK!uKAs|}mrtFfP}?}FKt)Cf@e6>z{N~5YMZh^nZVXW>dfkfF$CVg9
zDMYo6)9b1*cppDsx)Z0An!2v3>zaP8Y+fp9T)Nl*jLBe#iN>WVIm|LJ8CV~mor_AS
zDwi(xNJF95DJ~=evkW&WI3IB#O(_RJo@J;)W5e<QRJCcE22y0uUZThijf<zOB#REJ
z5R>A3A|z!VWzUV!xOhGQF-GgXr&H!Q>0*rF7DQk~=0;wf9LPycp8y-}r)g(Cpb{Jb
z@a0~EYFZA!wQJXCn#OtWwOi%Vrh-f|d`z!<R}~)>9}_Vh%k}3*VUd_D<HcSB@N6kI
zdhgynQcA&Ei?fzCRj7<oLjfNWwT%p#NaG?Q>JbAM>1p~w|CL3M{&#=+yQNdehY;v?
zyVz6_6>1l!JZR$O(-@@3aiU{31lZeelL*7}9O7WD)xpq;3fQ28Fni$S5YyC!O<Iq;
zo<j^ng2B+Li0nUn|J|kgfR8aEMHc`UM{Qouz$Nrx95|7J%=}b<kBL`})$>HaSZfRK
zz1jeIZm{FBcR1#HoQvn0#;H(Puhg~E=Ec7hFhD#DfDG7Znx+#%z{ZTSET~-~Mm;fA
zj?O7(xOXg#Pgv`<e)4e+Yyg9KPdW}j0d&3hc}fXPMNt;`5N8INb5K&{#E3W_)rXM1
zdh(A5bb%JIrv)H@q!_*Pk=^=D-rU^4xz!Fbvt{YU^Oq7`{c!N<-(ODbIZFz8!2bK6
zpM13O&3AqspV{x2FFrz5WyQ89Ac+X=u>bKVf4Kd@IQQGJO=lWc3q;;PwF1g<S{YV0
z4NUDxV~v0VhGTWh%-b?Hz8ps@J86cvpd1P_030iw0oSsYwXEg;TK)t6?!Wl)D7R_=
O0000<MNUMnLSTYH<ipYc

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/ic_action_search.png b/vtm-app/res/drawable-mdpi/ic_action_search.png
new file mode 100644
index 0000000000000000000000000000000000000000..134d5490bd3310559cc944d44d24857eef29f2a1
GIT binary patch
literal 3030
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
E59N2f#Q*>R

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/ic_continue.png b/vtm-app/res/drawable-mdpi/ic_continue.png
new file mode 100644
index 0000000000000000000000000000000000000000..50a54e0b941a21dfd284ce12108f62fef3ec5bd2
GIT binary patch
literal 414
zcmeAS@N?(olHy`uVBq!ia0vp^jv&mz1|<8wpL7LMEa{HEK*5du+<y{Tfqc#akH}&M
z25un`X1sK_?hjCqy~NYkmHiGg2dB6R!>#;u1_nl5PZ!6Kid%2*?B#7X5NJ!3QaiyS
zD5|<SWkLs|fN(%6SKA4WmoID>g#%byC&wsEY5DWO_`&xj{xO9LKQrGPQhN2<PPS;{
zc?IE{%Q~F&1RNL`Ted2c#EL(!jPqQ=&*vyMSEW<()^3-od;vRwWeoQew+O~DR<vGl
znZf*lZDH#N%?5D}-j;mED~d77f4CNKJrsHv&tS?C&f(3t!eNI)gwz4c7H$@ChU5-k
z1&QQ7-^)wRPfER+o43&D^Q+pQ-=6vRq(+JrbCjj+Kb{7*z3^&jEtj0*HcJqXg#clr
z7!q2_CwK5%!-njZZMpmhl|A<Ee*WUgyhl=kVc`l542MJ>Y6&cK6L>V?|6GMih8$Z(
UhiSShpqOCrboFyt=akR{0I9Nv6aWAK

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/ic_empty.png b/vtm-app/res/drawable-mdpi/ic_empty.png
new file mode 100644
index 0000000000000000000000000000000000000000..7e162eb62f625bd4e5f246c8be66a28aa4ff630c
GIT binary patch
literal 240
zcmeAS@N?(olHy`uVBq!ia0vp^jv&mz1|<8wpL7LMEa{HEK*5du+<y{Tfqc#akH}&M
z25un`X1sK_?hjCqy~NYkmHiGg2d4s4e0tO=pisT1i(^Q|t+#gqc@G$HI5^g6EmK;a
zRF&16qcS7IVv_g|J4TnZcl)=0Ke4D^U5%fGLqNfyfq{{U0>%#MhayL=a3%Wwn;TGj
YXR^?al`|%M0y>4k)78&qol`;+08Jk~lmGw#

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/ic_launcher.png b/vtm-app/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf571d67b031816be3218d94678db83c3152a691
GIT binary patch
literal 1396
zcmV-)1&jKLP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm000F$Nkl<Zc-rk*
zYitx%7`<(`lu{nnDl|SKDo6raBKv4fi-<-A<0D{d6)`p_B32PBqQRu_r-|{gNU(^)
z5>f#b^@qj)CL|=?nF0x-##9p9&??4MI@3UDN~N7So;y3cZI@Qkr8_%BCONsg^SJk%
z`+fJj_q$h!E7z54$P0}k3%V$UCTfU}hy^$)vM&$ve~B?9ztPmhSrRu*30-vXUhuLI
zL84EPa3_hwf*vUm5mA}~Mo2GEF)?ridHkK$cYDC^(ZmhJb<onc%U&m0L}81O_da%%
zyCm*YvCgmJfM3BruZk4~-y?@a#}hXb&lrZWk>yU}3!==>GD0?43sFlTa&L>1J)h=R
zjrV+t*%DCA#(;`OziR$LG0RDGC5eB)av3p;7!&)fO*}=yT`?EZVlH$R?czzt_!k|*
zWWQo6?D-~&Xp#bC>95DPHO<H;Y0sd#IZ%x@u^~=GCk4DCqmyF-9{mAR`U~*c0(=U-
zDfk&V|7kpmAmK8)%_a-Fcw9y&hdc*kiD!wWzA)C)WqzmYSQa2!_<ylG!yk}A6xjoE
z6>-fSVdQ$lsASLYl|ApP$C7&vVze8{XA&<HUlP9f=Y@wcUPhnP6YUUr^v9L-%VR_f
z5#s;pB)ytg>+Ts6B7<S9mNVnIev^zr5e?`nm#&lLZUMTuD>kw839!~GhSM`-f&!|{
zDCvFzEGx8$Ffq>E0@}qgXfXk?sh;R1_R+;M-7TP1Or!wKj1yo@^KIg3_q!0d2<w<#
zE+Y^HoM&lJKr1ctI(q)RS59DVCZA5cNj!qn;uex#L;>Y2i|IP@*;~XqIUl%Hz(d6L
zi%et{#D~N<w~?R3rEe|EsTX<AL#!Y+5Lda$b*kjzY#8rX5}}llF5QC+F2D+jMJ4rE
zaJ&-_4#zEIsz@xM)poGVb(B0;iXN^SpCf)``u7{x^2cW>*m7qbt{tZ3q=;9#4OFnM
zX+)6NChPVd#e}2@D6GSDuGbF{O_3DPDqFk?o=?F2(q<n<0XyMnG#`+;0TY{Qibzhh
z^4H-$Z#^0$@qVBsj2(&8=T(e%0}5Jvs+EyhV1363e^LYl!kEb{>WEAOV*(VjS?(qz
zRG(^u=r$+pl+sEqS@$orXi3ucaQtDsMB>d%zE4;t592dyPbU$JDkzgX5q-N7R;TP|
zf-@;;;~;nv*{d2buSmsfB(ShpNql0OaS&q}&EB90jw|ygTH(9OUvWRj$MwmK{rL=m
zL6+Ik{hdn<%j}35zB&{K4j_;9781LY7GhcPTw+a<CrH`G*Tjv<sJvP>;J^$&pO)Ur
za>__n>|v!LmJ@^n7u$KjwnY9&Rd^Gz%i;CbZKi2T5i>`kvN^=tDOfa?5YnA)$E5@f
zyQ0TZwDOhFX%BI0B6~hr%xmXD_f%PE7Z3B^D2D~e1>jU7i0;kPn6AD`>^IxQUS@w4
zI3uneihL$tSj(4n>tG>rCUwTpL^Ya)<NKI6w|+9TQJ<1WFZzy{ddP40pj$WW?fHDz
zj=qBg(>@XDA{^gICdn7sZjY(Q9dKx(o6nXG_QCu1Y2ZKsx@C=BjtkI4t-bqa#tD#o
zLW6y<slR{$(8X6y3ovx?iG8#>@RTwlpk^=u3*`}JoLXst^K`ElQm}<NkEGi#I3v^O
z=5+T9Kaj^cn%IoU*=*GR|KT9siPIw2aRCe*Y<~^$w;ae6(@RdLtUxo=85vqd4%IC-
zA|w5CzPvn@o3)IL9=1P+Sj~>D#3^yN>-S#&ch|q_k2o7-0iW^!0000<MNUMnLSTY%
CAB&;@

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/ic_layers.png b/vtm-app/res/drawable-mdpi/ic_layers.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e54374c9a2b496a2cb651792910e8a2dc2c39de
GIT binary patch
literal 1833
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
E1w(5%-2eap

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/ic_menu_mylocation.png b/vtm-app/res/drawable-mdpi/ic_menu_mylocation.png
new file mode 100644
index 0000000000000000000000000000000000000000..9d1f4403a931ada4c33f5fab6123e5869c913804
GIT binary patch
literal 1409
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y
zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP
zs8ErclUHn2VXFi-*9yo63F|8<fR&VF+bTgE72zA8;GAESs$i;Tpqp%9W~g9hqGxDg
zU}<8hqhMrUXrOOsq;FuZYiM9)YHnp<r~m~@K--E^(yW49+@N*=dA3R!B_#z``ugSN
z<$C4Ddih1^`i7R4mih)p`bI{&Koz>hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83
zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0<RzFwUtj!6b93RUi%Wu15$?rmaB)aw
zL8^XGYH@yPQ8F;%(v(3~6<9eJr6!i-7lq{K=fFZSAS1sdzc?emK*2fKRL@YsH!(Rg
z4<rKC;p=PVnO9trn3tUD>0+w{G(#^lGsVi;#m&XQ(Amh;$-vFf(ACh=#L&{!#L3yw
z&D7A`#K{n**Cju>G&eP`1g19yq1PCvUQlAlEdbi=l3J8mmYU*Ll%J~r_Ow+dR=1d2
z7#ld@HV>*d1*==YdQEV;MIY!GeNfaQMKw$an0`P^c)|s8;7LC<518JIfC>Bek$Ykc
z42+*WT^vIyZoQel+n>o%;F#rsQ{DVgCIY%VT)kpWN@80)lDBNxa5O49xx4p&!_>8N
zxx%*HkWl`?W!KcXZHB}OfphOCy`Q9eZujGNPq=PAnf~VNxpREGt&O{vXmp)F{p@??
z9X39T(ggM=b0s*eN)qI1s<tvaKaeiDx&7)Axx)cWk{g)P4zdLB)-+TXaOr6j-))q*
z!OHzWET$>E&$m&fqgi_cyPQsBsO$y@sXGly5loZ%`i^W=D!m+*6CGK@7IHvwg6@mc
zSJoD+Te$D0;EKQ^mSYF3GJ@ooA`Onew=Q6l`ZMjIp>j&|^sCndQw|7waBZ@%U^o5X
zku~Kg>t2!PX+75rxDU&$_;e_9e~rA$0rB!BC+k|06<<xWG=Hwbe<Z^r`_(r8=4pL-
z-N})TVas?|PWRctD&%937$AP^it&31i#vkvTKkLDEBl!qNQs=0kziYF^2}}Ht4|$&
zs;rkkcW^vWr79qL?8@zZSsNl6tfIP&yq~?j!`OOLNA<*&fa-^OFW=rVF5NQC=yXR~
zbj_jP3oI8N`)O9etlU#R^RLx$sY8!AZ*7R>-r{1ycWsY{OZ~jAYF#(gZ}r-4r>|^`
z>A9nET<G-2MRSYZd~p<7_GYg<ztCRwn~amMsbzfs?R(?dp9Oc1-mMS~mn_;g+vG?7
ekN2`a1QQslowEJ!+xWMG3Pn#>KbLh*2~7ZF9Rj2P

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/ic_menu_options.png b/vtm-app/res/drawable-mdpi/ic_menu_options.png
new file mode 100644
index 0000000000000000000000000000000000000000..d3e42edcb6db096d90d1b28a2d4609d3419c5751
GIT binary patch
literal 1339
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y
zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP
zs8ErclUHn2VXFi-*9yo63F|8<fR&VF+bTgE72zA8;GAESs$i;Tpqp%9W~g9hqGxDg
zU}<8hqhMrUXrOOsq;FuZYiM9)YHnp<r~m~@K--E^(yW49+@N*=dA3R!B_#z``ugSN
z<$C4Ddih1^`i7R4mih)p`bI{&Koz>hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83
zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0<RzFwUtj!6b93RUi%Wu15$?rmaB)aw
zL8^XGYH@yPQ8F;%(v(3~6<9eJr6!i-7lq{K=fFZSAS1sdzc?emK*2fKRL@YsH!(Rg
z4<rKC;p=PVnO9trn3tUD>0+w{G(#^lGsVi)$k4*r&A`;u$-vFf(ACh=#L&{!#L3yw
z&D7A`#K{n**Cju>G&eP`1g19yq1OzjUQlAlEdbi=l3J8mmYU*Ll%J~r_Ow+dZnqfY
zG!Lpb1-DyFaO%|uIz}H9wMbD769T3m5EGtofgE_!Pt60S_ab1zzTW#wpMimKt*47)
zNX4x;(`~&EJ4hU#eM=~Qh3+e*AEGP=FItrrTsY|WOZ1EJjvdw(oa_9oZXR?!=qWq3
zDc-Rl$fx$;g=0VJAIMucT~d2m6!_%<`}Cr{HsA03uk3vKyH4?Zpw1JUBJ%}HD)(!x
zD6V6UWBYsX(wau*4TpZR-Y}|UE&5gYfy*j^@ysj}hnSn8^Y$O`h~hOlpeFH@&9n6n
z+cyXQpRvy#C&-_<aKOKSNAEFDLF3`pOrDDVi2RRB`R+e1t~b{f^lK8E@#wVO0k#T*
zrHqz^k(JYae=q3_5ZULo$}s!L)$a?O^6xad$5uM@zAxS&yLla(nC1SfQ#(|q`8WES
zd(T<_@rYZN;}5;vB9Ura6C_QhUbbsoJb}^n*jK(89+K<y_EvsPUX>`sd!|u1&Gh3b
z<B0Tq=8G8hx2*GV?lDynI-Ps0taanNFPw+jR=(WTl<-*f-1^@V6HMY$g1A+j=Uw!6
ze3;31sx9&x^F4#V4s*G-w`&}4Us&hBBf-2oA?l-7_jQTP2H)^yxgK7E_r6H#hGuDG
zc)YQ{%r8><joH&}hkVBCH|%w1+fV*Kp84vd?g0jm$*nw(?nc>xiZf4FKbLh*2~7ZL
CljEBJ

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/info.png b/vtm-app/res/drawable-mdpi/info.png
new file mode 100644
index 0000000000000000000000000000000000000000..d7b7e698630e6b7b9235a937ae682db2ff94e851
GIT binary patch
literal 1333
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y
zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP
zs8ErclUHn2VXFi-*9yo63F|8<fR&VF+bTgE72zA8;GAESs$i;Tpqp%9W~g9hqGxDg
zU}<8hqhMrUXrOOsq;FuZYiM9)YHnp<r~m~@K--E^(yW49+@N*=dA3R!B_#z``ugSN
z<$C4Ddih1^`i7R4mih)p`bI{&Koz>hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83
zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0<RzFwUtj!6b93RUi%Wu15$?rmaB)aw
zL8^XGYH@yPQ8F;%(v(3~6<9eJr6!i-7lq{K=fFZSAS1sdzc?emK*2fKRL@YsH!(Rg
z4<rKC;p=PVnO9trn3tUD>0+w{G(#^lGsVi)z|q{?!pPaw$-vFf(ACh=#L&{!#L3yw
z&D7A`#K{n**Cju>G&eP`1g19yq1OecUQlAlEdbi=l3J8mmYU*Ll%J~r_Ow+dZnrq%
zG!Lpb1-DzAaO%|uIz}H9wMbD769T3m5EGtofgE_!Pt60S_ab1ze&V@(9|Hs9a!(h>
zkcwMxuG@Pbc93BEux#V3ATGV5T&+r5BIaybvAa2<tGT0&;iI=jXS};6pI+fKu1A+n
zD(QB_>Xd!qkIH;3T*1V*^Ul(3a!!180#)Vj_p0oz7Cu~hx8>Y4pNzahrdz@@B$NHP
zrX_NU{k$z~bHKL7SG!T?&0)PM72ogOoZhHdvVd>-hebkH0`9cEE@09w;GTY=CH<Rz
z1Mln&T;&Bk=9f;yF$tMwI5KZL$Rn9u<kMW7wdu#Eqt_)~Fm-XA{M9w*a#GJmp%YEa
z*8@0SY=1CeO~XH?=T<$UmW|9W+U^|VvI$as^08D>yFm8h`~tCa51GFuh!~{x)y7#j
z`yaG?{55g|GxOEv6Svb+3s|~;KR-AjsL4?In1=DPPnHjO&30aO$(8G?sAXN>ROow5
ztFT&2bwa!Oi}tq(eIM7mu03D)vp%$^$|kN@I70b&#9j@~k{{1EsZVJ5yV%dgYXNWc
z{u&?8V;Szg2?tg^6P>nd#e|R7(kf)Htm+Bmw_;8?>QN@LJhA!GWs9z@;*0GykKc;-
v=;4r8i;6$F>|0RQk@;zbOuK}Ch$S$X>PoKli8&MkD#$!t{an^LB{Ts5qQ}~&

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/info_window.9.png b/vtm-app/res/drawable-mdpi/info_window.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..41503968581467a613d3f8b62c3c5ca956642edf
GIT binary patch
literal 416
zcmeAS@N?(olHy`uVBq!ia0vp^E<o(S!3HE3H(gu;q!^2X+?^QKos)S9<gg`qySp&_
z2f+n<mrn+Ya29w(7Bet#3xhBt!>l<HKtc8rPhVH|JKQ2XCS1X3DGPw6D0sR!hE&{o
zJHwl=$w9zncAMz-%hnZI?+?7aF@f`Gn<9%q>jU+d;hlv-=I0jg+LgKa@ud$xm-_wZ
zKl-6|<{ahKD~)Ds%YFYY&W%M`^J;0WvGHk#Gk3kq*DKvx^#1q9H`-5yqxhH_7*hQA
zF|o8WuqZJ66cAv2rXb^V62xIVQQpA8W04}vG22LnNuWU{)U^6w=dHqN`sI^+7BL4K
zNvj%LsmAQ}dDr8tA=z-D%s+E?hGqMP(&LIPul5B@U9zZSyWGrUtdn24tq9UTqj-9f
zV#rIQl9{p1k*4bxFZeAWxN5yy`7J%kO<_i?lAm-!p4+n&pLiuBRH?eD#KUXl<P<@p
zlz&fxy<+X2-;RH&pO$v5fkClF!0Cnmmv?j4X_VJ71Ws%cmAP)R8W?;Gp00i_>zopr
E0BEY6<NyEw

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/moreinfo_arrow.png b/vtm-app/res/drawable-mdpi/moreinfo_arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..04526cc451859ed60f507621763b28076f58e4f1
GIT binary patch
literal 1500
zcmV<21ta>2P)<h;3K|Lk000e1NJLTq0012T0012b1^@s6R+DEB0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU%en~_@RCwCFmupO$WfaFxX-nJD0R_2s
z6%bG{#$?=t8JP3KK48?aOE$A524k`qrkOEIlxc{XnJFL4qKU>VB*qO{G!w%Y65s<G
z<!XoyWQ>B`*M?gu^nUYyUfx3AwiJwsPjYxKea`tk=XuZNK^6!E=>HxH{&Vx@&3~no
zo10rQJv}{zTMK00t3H4J{0?-FiAhGI@zT=L(z(^u)kho-hkRjSfwHr+3A^OQ6mwi$
zTtD7_hTr?}?A@2AyTIZByVlv+c~LHxD>E}Qsi>%kv|24G6kBQ@k4Le&xv4jqOeY>Z
zc<@4MYU&?$yZr(dFdS<KqC%^xs`7`2hr3`fmqF|myos2nR4PfQ(+N^oSf~WJw7<Xq
zH?>;*rPJwrYu`|KsPF6R8}|8p2TMy!Nu$vS@9&%3)Ms?i+^UBb*0y#~uTzjAMM)I}
z8hSJ{o(u*9FHi;j*A^ESRW6t7ZA^2-gaW7;8XEc?-|FCzBS%OklhN#ohi>;<1!(w~
zUiJv`%YC~5J@a%TJ)Ekfva&L5Z*T8efNfa(<#0X8o=r?lv@9<#XOxtb2*4Q_{G@%E
z{+f4@*BjWDBz2tRnT6-@T-J$?kEiPDYF%Pt;%S&Ywks5qo|>7Nd69vv#2#GzX^GYy
ze)9MN+ww|PGJS9|owAY@lJ_h;mvvZ|7Y&cI5p<0(uZjw_TCE=;GUGTXczpA-g{*eJ
z#G98Z66x8Z1C*eW(Uq4TB0a$29<vVX@<>llSEi+<rQr7Y-Js8LAaFX|opaHjv(5-l
zx<_ra>GTWp6I5~Z{)sfo)<t^Ex@?07qB;|oQxVYP$B!RIZfP?zGK81icQ+$EV3|ZP
zUAb+h4H2vb_`_4_bVwKJG27sQXih_(AI5Ex1iHSyUcosROnRf)9kKeLOaT1OccvXM
zg6is-3_6r5^_Xo4=>eOF5q4WIfuf2SkkH%i-(Pe^^)x6Gi*CC7t%+<Q;A2l{C3DzD
zZ~$t<<&Y##y<V?8wBi`ej=ejD+)uucLT9mgchy5Av)dYpr+7JuI=VfnNUw?sd^}r4
zx8BI1M9tPhtw@zS0~X1gP#Y+T{9uwmZ8lpEehBOsRqqMZCCImdXRlAwy^!q;v*ANI
z)Z)4zfublF&1SQAetw?Y6`d$g`cFU}Y=do0PEL;b{r&>HT9iOhbA9-(QzIiIgjz|@
zJeEM^1qY%SO5PWcb=d~nLf26v9ml}%M-&J2&QDiXR(vQD!t;Bz8FWx1ZD$|1ndx?~
zB_@z{SeFMH|14s~Ff}#xl_aou3lK;g#VI##+~`H=%B!iVks+aJWX?(FzL=p6hhJh?
zuT!GEd7=VuUCf~;4Qj#5mX?-#8yg#r`uh4Ba7^Kz`Z!&?y1HInTU+y^y%D~Hpv*?X
zw>lb-=LCVA39!|LYidVFM?HStlyL_L>!%#K&eqn}(X6bj*KvOxl|)lqTr3!AeKUu8
zC+ze?pM}O2oZH*VfmNhe)2WJNsw~`E81Gz9Pfs^`Y5DBz?6vmx_HnV12g0{E_{{mF
zYiw++%gf7aKrL1tJ$h6XJUzr32t?i;b6Z>6-w2$;qobpjnwpw^6i<w<;DVw-Wg<Aa
zuCA^Or-#o`9<%cE^WE@Tt5QWT8WxMiJTNdYi8E3@a?(0DIQTB&<JS;iAQm(ftc8b3
z4Gj$!a1uO?`pFG>6^rmeT+nl)sK@|OBWM!fsRhycJ?4MS^#-yL3fv1C1am?rh@!5o
zt<9;dtUL*z9vvx-Bi`+Ho3WKs<KyF9&CSiDB7}i<F*qg1(7m9caHZ(EO1zhcM7>`$
z?iPiip54y8`-O%#e1!;=i4uhR#QT{4Vg#Z82rvNN9ch!|eHB;$0000<MNUMnLSTab
C$;|=)

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/moreinfo_arrow_pressed.png b/vtm-app/res/drawable-mdpi/moreinfo_arrow_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..529016152379d6b3c016f9cde1d892bbcc701580
GIT binary patch
literal 1582
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/no.png b/vtm-app/res/drawable-mdpi/no.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ce695e551f857f477d7f394446527236e63540e
GIT binary patch
literal 443
zcmV;s0Yv_ZP)<h;3K|Lk000e1NJLTq001BW001Be0ssI2{21+{0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzT}ebiRCwC#R@;q(Fc3^m`G*dm1Ly$g
zfD)hsIzV(l2cZK>;HUuT;5vW~?nYk8vi!p4?xcKVJ}l$dJMrx7!tM6POX2%3Fin#f
z^C5A3GF<+PRaHqV8iKCtE)(Q=F0Fk0x9moOD2m#)#b`Mk1i_O56W1goD4pE*9gi53
zBr!!_mW2{Kjw3Bj4Cgn9<2VdMOfVuVDhHxtJxx=3q|F`@ZQC{s13xTrNYRhuXqv`P
zA_Bza?&eyF%BUKu64?k;jx5V8(X|8*`<?2#=H)|L@t>d!Tn{lX+EnD=`S6YIT4=~2
zB1$VR(VYm$Gm;VezBko}AA#gZ4pV*j5vYF0+)^KYbzt$kwm!V;0PV%%cN2$eFB02}
z){&xjv9l~o?;Oy1i{C{K*O#E$Do%msA-*%bTg55ndA4u3OE>spxXcG1uj^VAh5iP=
l`JN!G4DS!X*TRng0|3f!iSjFnU*G@$002ovPDHLkV1ltt!Z`o{

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/plane.png b/vtm-app/res/drawable-mdpi/plane.png
new file mode 100644
index 0000000000000000000000000000000000000000..4bb11e31582a68258e2c2bb0878ee59c1c3c1533
GIT binary patch
literal 407
zcmV;I0cie-P)<h;3K|Lk000e1NJLTq001BW001Be0ssI2{21+{0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzIY~r8RCwC7R_zf)Fc5XQD?kURfDW{v
z13EwjbU+DopaVKU1?WHrZf7!QjE}fo$^Obn_Px!1Jkd18_Lh$5x^55zu$ZPve!RZ#
zFFyk&h3H^Ok|;!%e1ju8eBoQK<5ANzQRup^M^Uu>0!1#%^8EDj*w)z34JtDXgDUjZ
zY}?MV49f&A=<1=E9`&VR7-1N;ZL5l4TO<?#!}fccrYIMNLNAH}dt*jM$6ke^1iP9O
zi!9I?=&Pp$0(9QHw*((PO`hiwR1E%EUDr8|a}#D=*JPd9X6bScpgqQM6bEsoz)jOg
zkR7p#tu8l{-1mJP$ChP5PV+pU=Xu@Qu8&q#6>iWt)Bi&&KFMfqyMP2GWHh(aXvCR3
zF{tfxp=adeN+3XGiTL=1w1Qy3Rg}DBrPx=10RYUba-!_vze4~3002ovPDHLkV1f`D
Buy+6e

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/time.png b/vtm-app/res/drawable-mdpi/time.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac323b97016819daf86c064d7ddbd281e5ab2886
GIT binary patch
literal 597
zcmV-b0;>IqP)<h;3K|Lk000e1NJLTq001BW001Be0ssI2{21+{0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz_en%SRCwCdmhY9pKorGyo&8P+bPyfT
z0Ugi*9XKkW10|pWRDcSU5GvUH9oKnhBs0lG@@3~k#AM#RZ{D9f^Y!)L$9L(9cDp?u
zk9)n|a5&V={eHh(F302XbUM`{9}EWD?e;f3(llMIR^4v5GBjQr^zC*71u}pRhr?pA
zNRnhSnQS&22t>nVEOhc5vIH7j_v>gha%b=ZXf1}DzflA-!0Sk#*xC7f#)M}HhoST2
zJ->h*c;{!cnc~SliU{NgyCwl(g;4Swn6P6r_oK_czy&NtkV%XiD+Rz`S4H3A2y6`n
z<_WI<Lq!6ToIZ!mwDd!-^4#rqHHG2vcmUGrbS#B00?ELBzppPo^0MFWzY!ocXiFpN
zhD^BxKlT9*qP$!#OCi?lHF{@%=kxjXdbJ!(r&C^t(wmK%tGG=p$(i96zKX?D?&VGR
z>~qw~g{HHx$`_Rf4fio_BnR-hQr5D}kb_T@JvUU4N_AEzc-AM7B4vH$zYc&#;^R*z
zI#HyBRowS$iL_8BK}h#QL+e$?Mb)TGNLDN5gY&~qs**}kpuDF_!LYL^e@q2A@Fivw
z_^bPe*2fmQc|={gX1camW82MzWtDdPa?Qde2+-B=da=6~lu;L!5Dhy3F@L8cGF-nt
jhYs~oBXZK@_!D3Nx^W}TTpQY)00000NkvXXu0mjfrPLDh

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-mdpi/yes.png b/vtm-app/res/drawable-mdpi/yes.png
new file mode 100644
index 0000000000000000000000000000000000000000..4af8e767a9ea792c418ee9f908effb9551271c6a
GIT binary patch
literal 377
zcmV-<0fzpGP)<h;3K|Lk000e1NJLTq001BW001Be0ssI2{21+{0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz8%ab#RCwC#meCD_APk1@jPH)%2)cnf
ziH_g~>I9Bp9N{M5+<*;a1UI;AFd?QQO5wo=|0mLret!#8U#~~E($9w&W80h|Vtl2@
z7OSd45e=a0Ix-;7a})_&S{lc3mSyHWflGEF1XPTg?hVkk?NM7i0KmRFPxGY+9POjE
z9{{pHO_OK9b^8>6m3<1p%Dy#VYabrLsr?f`(=_mi`o1UI*GyALx~`KXQ3G-q28cva
zq$2Y?Ycnt@)38%omIcj7=!uhkQ~{_gOYOuzvahYcbOz%%?&rI${gYd?XF#JM=nb%E
z*mgg>vI!V)=5<|j&aLcU1%N(Mgp2b=w@65lzd~u6LX|~P=qqsfpIF7Eo*%$_=`X+l
X|3Uwd8AP~300000NkvXXu0mjfBHy3r

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/direction.png b/vtm-app/res/drawable-nodpi/direction.png
new file mode 100644
index 0000000000000000000000000000000000000000..7056bcfb266d02c059711f62efe2fcdf31b5f51d
GIT binary patch
literal 1826
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
QkN^Mx07*qoM6N<$f~7iJa{vGU

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/ic_launcher.png b/vtm-app/res/drawable-nodpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..5e951fcb7e995db60612aeda971fcef2e55258d2
GIT binary patch
literal 3907
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
R3>N?Z002ovPDHLkV1fw*NK^m-

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_departure.png b/vtm-app/res/drawable-nodpi/marker_departure.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a7eb979c81a72691c781f6545300954c8ab015f
GIT binary patch
literal 1413
zcmV;01$z34P)<h;3K|Lk000e1NJLTq000yK001Hg1^@s6U#j`N0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU%CrLy>RCwB~Ra<OSMHv3i?%B4xUAw*P
zvRjG>v`~swK`sHKmIzG~V^D(;F<uhU2VyYsp&Ao;;Q@?^2?@%B&yv(jgrGswgaD~1
zky>@7TzZGnrQ3E-_j-2EZN`6Q&gpim1Ri>l@60*#|Nl4tZDu66`|}WDC*m<gl|7e5
zL=k5Z!~bU_u@|MZI3Y<s96m(sfAymmLo3%Uhfp|(0t$(^0weu5;lz=X3d+Ak97fyB
zJlj%2oLKov=dK=aRYk+IyE~w{z7=FiF7bd+3kKp>;ipsGkebfKzxnKk?P!19A(ZE_
zH@)y~M{o1y#=x!}yZK5cF~9^JDA+5r#Stq)O|bu+COFe`I$S7dm(g|`l3rnQ*(UQo
zf1v$*%eJP#&Zj#-HL@iHbGcdYv~7I`3`_T;-)E6yHBO}+4?pnu<%YH=+aRZ>`NUX!
z1Xe^=6&V*ilsf{jZSxZ_bY*l2{vJehy75(yIKJ<bJpr%J2fC$kTpzd!Cyss#RjVqX
z((ebIXdDJYBSOdduU_hhyq14tEIQG}Jly`&Ya1V|t_eU!OY)@?g*c2%4MI;>FO1$E
z1<N#G-5d2#xx5^F?n<aCtAU#GAk=xo5UdE}f|VeZ!2`&(gAr~FHZrm_+{uo^q<S0T
z>I9@_G#=XRUlM#YEsKv2zqu5Y$PA3aAh;wqL@FB)%OKQL&BU#Yu#Wmn_#<`^CXtXz
ztN;|KRhqo%%Q-&w(-@Cp&F(OG8wtdcV-QQ-LW!S=1B_6L&)$J_%Hoxzf)NStQVb$W
z!bV~`lNMyM3OH?}Bq!2P-r{4MVXjf;?;iF9H~9Ftc5eja5D}y%!dA;q>EN_YuQHf}
zP@A`;--sP@-FiXPye9(gAVImsJ!5)gUXLmRD*L>`2rtAhWn-&fTCx=UR?$NwtbNoA
zYhDh6yO!{<2ztblEMX|b-aSm)rMW>%8*ERXV|~azstBRmtJajE9hQVpkUcU4w^o2u
zfhLy78BYVs2mvutk<;;?u|s;&pW|$o+xEKG6L7s=<|z-9)iNa{bz7nUoIv6uCoKU5
zb%?-Be`Yd2Y3^mIbTPIqpEhI@f2!@V-)5EEAOT`9P!7wa{NEWl?C-)&3ghRMbmFgk
z2XgQ-yF>v9Y&u+jLy6|w$1f-<NxFoQLxOUP6Ny$~bC8o^tUIAA|Ky+Bbfi8?Oi?01
zXb9uS4@LTB`wMRkem?~+;s&N92ryg&?0?pP5)7T1hUC@4`x_2LdK~-z5HhSk82&nS
zUHdA2F<bPIjTV{H$y~EQ`8$6Ob&u0|wnajd+Bvg5z@sQRtg2E$E+s{{i41pspJh59
zvtD()X7(jHqztBL=+@5ASZYA~V)9a^=$XOf1X4FNNDt~iwsr=8C3ATd5tM|?s>r}d
zsSqB^#R_>hDdPrgn*ru^s*m4E$DBF7Am*1E3q$4#tUW}Fv>d1%PY>xQ)msJ{VQ;hM
z&bc5xtVLVitLvtw(^596RT8qZnmsaQq3~VeT6V75sgXRJJ53y2t7v1{MUm~(hi@ys
zH^u1%;tzWCtf|T_kI&F`NDgztGrVw;b1YDCzt~%jd&olNs}bQX4<Ey5+*du59X0v@
z4{wj`VRNj!(PBixP81XF`#IX&v5ancdo6RM`(DcOeGvAiCR8v~emqAPgYaf{N(FV6
zUs~4|gK$PwbSLY#7K1Q@RdouPzL&D=J_u6?)&5Q_hKGz0FJoZ0*z~=W{}o^WF0g$9
Tm*SS000000NkvXXu0mjf=^%?E

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_destination.png b/vtm-app/res/drawable-nodpi/marker_destination.png
new file mode 100644
index 0000000000000000000000000000000000000000..9b0afcf399b0ac2fccbd0890ddfff7d747b786f8
GIT binary patch
literal 1160
zcmV;31b6$1P)<h;3K|Lk000e1NJLTq000yK001Hg1^@s6U#j`N0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$DoI2^RCwB~R()t2Wf=cmn$3Q!?b2(K
z)n&^Jg>}+Ra3WagTw6uN3j1ecu*o(RkqQ2x-~^qDf<sW4h(lxu8=?$`OgHD&Emj$=
zY<8A)oyOUAHf@^LHqFQ7t7-1e=e^t|m&-?o^o3vEd!LWr`#jJ4-gDtldN>J>6CNPc
zsj?_xh~OrS7IWg*k1WeM0moI-bg0eYc*R;>y?V#yRx~%Qfr&F=bb1=!4G+UFL?iu^
zlgG&J1M(GgzWIbCxUa+MJb%B{+VbB1eQ0QVv}owzYgh69i4(Z)n;QGs>wTL1Jq3ic
zXl`4(w(pJ34qNxZm-AC7G2F+G<LwI<g8e?<HsTm&gl3hwYMaAx?zP9-ZQaj34<wUW
zC%Ft^=ia@5BwF6-xpbB|Sgj)_Rrh+U&ARcKJ<mc;Bmfn%Zr027`p%uZ(7xWWfjACp
z88tm@w-25@_>#S`bxU^l4|{*Y_+q;F@vkuBP)BF3rnmpXlSe-Z{x&nSm8HDhQhAS^
zcQr$f$FoMBh)^<B4+W^Vt#hn{v$obkgk6kq>l02V<X9|Iv-x>QV`GR$qbN7hCr^SS
zKhEU>*U*5cTpMtDWTcf5@~-+ih=YR=>5j=B52Qc<;jXT-gekW>a|3uD6)i1TQ@N6@
z>XlOtjgDgB;$_IGh3r)cg+gTs+38EnmNpmr`VefgD{@8{yy^F2hf0<$bU0j=P&BMZ
zQYkh?7~w##5W}0sw_yoF$*}GblrtD+gujH+>6u9@Z@+goprpc5Zb>FEkQR%QJ!G!P
zM#yXfyam2MFi4NRn$5f2Rh6=zO7nlPdsPjK<0D2?p%M-(rqerXtvtUeo=~DRLef1$
z_xz)+5nl(xUOGa050Oxm-i*ygYJk&U*c#;tvi0i0p-@KnhHTdZ^W?i_LSK`ARM2>k
z3<NhB(ptft67#QCUS3CSgnZhW?;VxPq+J0q(}I7eonP4h?;I9tsuh{6>Lhhm*7PpF
zI3EH<_39XKMbwqTq+J0Ge*>q;@T((ql9G;0duHw86untDMX~oba7^TKx`GJBoZ_%M
zEC^FpK2OdZlXbQDY>t%;Zz)7_o?nhoAI%?BQi}5PkE!2@h77)4xdJ}m+%2Hrm_c63
znj)Rs?bGYgcsy>Y&qZlA<I6x$(Mg6tN~Wysb_1B8NX}d)5=}nduo_-j9wJ?jv9?mN
zl%>KQPoD`3*~9o@agoWsH%3-)C`KY3;g!i$N=UD&QS_H0O4B_r7D+e1hFm5B$$+cC
z9Ho6DP*n*=niR!Z_RqnXs#K(%l^aJ7Y~Cav+5QN-yFE)8o9}|~)<`IfNTz`fEeGMa
zm%e~AG36`w=W-Cv`J*wY|607uK`5j|No(YhrHoB?LC8KX+E+cW91$|YDMA%tb}8fk
a1Q-C$Dn7Omd`o-)0000<MNUMnLSTY;1T6^w

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_node.png b/vtm-app/res/drawable-nodpi/marker_node.png
new file mode 100644
index 0000000000000000000000000000000000000000..c4546d59f04adfb7263671c018eeef2043ca2811
GIT binary patch
literal 611
zcmV-p0-XJcP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0006iNkl<Zc-rlh
zKWGzC9LK+b4DTSq9XRyH41z6mNFYOQGu<K%w&0LMA+(O2TDw#iO&2XVNDwrkAS8lv
zb&5-A-0F520(XlvqYi;Sh;VNRJb&+9qFJgJR7B|SINty7=e_Uylfqw))CJ)G0C;aa
zS-w#QOEZYE04P0t*M@t`{pI+dc4)k4NVn<&W6X#{m#Kz+f%>yLws*Eua|3FRYjSII
zD;7(~b>b`6Da)8YI#PT6`T3A@0cWE~Ld|$G)6btmyx%EnSoxs``)YpDGj6vmD><O?
zsv%3)N|ZBbY=kd^5W&+mEM<gl4}^)O%@!7}Eb6k6HqiOd!N#49R3gCX;8Y5wMJwP+
z{G|)W6v$4T3Ay@BEZl9v&MxXzS<IrmoeU841IY!cj3NY2uEV)3V3W8x-3#(P90EQ;
zviCe#mn`j6emS2EaPsj)s?Cc=XE5Hn$YnSfV|qpEh^kbOVsFS0-S()?AP7UgkPvX(
zJtm7pd^Cq4oZfwy;NLe?rG$iE*oVm2x~%vsrIloW-3PnUDLAnd*~0h$PQL~==Gt#Q
zCh^=<9QuCvJs*3I_L2cqwAwAH?9c#Z3#XNY``R9VxduKJ7x9YR%G!MQV7<C7i^U=g
zX6RYRdw`jnOm~IE4a#?pI%vOc&j(PkdUI9Z2Q7~Hyhrp+ZBd}^QJ3DO!}*_z*{D=2
x(#bjccq+@3c-RloJZS#jWA`WG0`Ttv-vB9E*BM9-HXQ%}002ovPDHLkV1fqy9$o+d

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_poi_default.png b/vtm-app/res/drawable-nodpi/marker_poi_default.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b8d1f1a55cd5366a562b649bed00736740d2132
GIT binary patch
literal 610
zcmV-o0-gPdP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0006hNkl<Zc-rlh
zF=$gk7{~vC4)-9!d*IMFW)N(lLjoD{Hq$NQU<(d;R0yqOr`9gjMbkwK4iW@SDF}&R
zdFd3F(zw+v83K8WG@}lI98|~+56<uI(%7Z?f{F<J!sGJs?)`uF{qMU=;4eqw3h;jb
zg7<+e+$n&~Fo;Od2-FW7@bCG*{QjpCs;{fkFZn=(i8x4H=QL1;%F7Biw>A?~1Io|J
za$|i%i)m2`{!Qr7PO={p>3!wZ<&aAOqqCtD7gid6{({2R2Mr6J6p*>;>Urny9mk0e
zsJ^Yr{H;7J1){IR{#Pu&=s_gsO$DNd+WI`^Zp`Z3nz7LQ*u>iXwL~nyY5!D02&f9e
zK8OE?#BGn1Q)90}*!1i@n8jSm)m1snftzyU0ean@<bsn;!0qQGeqD(xA$#mQl{HY1
zHiCyKIM*EQRc0X*4{-A7M5@gjo{iuiSm4Pt7-PC3)uLu^s9gsg1S=!5h;o8tvM~Y2
ztz#*K(5)E`1RixfaM+U#W%}XR&9>nth0bXOSj;cR18hIumR{B~as=sfhH{r65z~IN
zh{V%IT!lIx?M@pzPj})0RMhG<sq9byT?q$vLr>dNUQpuPhznD}a?zje9ITdBWiFS4
z#VoUGvS4!PB8<g{^q*SvsEPW!`g8ylOLv#_dC=l8{XU}Kxh)FRI%=VD*qHvRxERG!
wQF>|5wCDIv3cGX;_V<48vilQp1^D-X?=M={8Fd{;o&W#<07*qoM6N<$f~W!}IRF3v

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_poi_flickr.png b/vtm-app/res/drawable-nodpi/marker_poi_flickr.png
new file mode 100644
index 0000000000000000000000000000000000000000..13d569af3d528670683e239c4da923c460416ae9
GIT binary patch
literal 490
zcmV<G0Tup<P)<h;3K|Lk000e1NJLTq000sI000vR1^@s6oswPh00058Nkl<ZILl-B
z|NlP&3U*lR2E@HUd>n{BK=E;?m>Y(AC`L9w0f>8m_%jgy$A<qoEc)`*cJ8E?R#TO+
z8w4?AF)jnp@jIIt>yI1NYcen}FrpjOL#!b%e8;?Z5zruBm|?Im`An)ozw8(MSf!nt
z2{eccY|vl(MSY|i0>g(4Yjy$+QUGFRhTrxJPLXTSUGv^&Ktr6tUIfO(M{*4U#^5iY
zA;~~23G&(}at-=oJLfmhkV+s{WdL$6kZaIo)AkQQL)w5?o8h6wgazapv_K>6A>5!H
zdS!_}?dJa^)sSy?bN@t&S)PP@4HQrZ4XSsNYS285)JH(QE8u|*in=Iqt7xEM*NHV`
zvu@D~EpF+9K)wC&=m#ezV4`vr)G1$~m3;-|WPIKMxddp)5ulz0P}e{bBsh5klQ|F@
z0C8@Dgzc_{8tM0eG4c@<y&w!?&(}zM6eebV0jOpN)R0`L9xiyM1!X*_^9-Q2^h5o>
z1&DV;@fN69KU9qYYNmx10}#WwpiXs$Dz1b^ZyS`I43$%Ws%6A1*boLXLv50TMyoay
gt3t&<a?I%Z0D>*&G|VwbegFUf07*qoM6N<$f{i864gdfE

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_poi_picasa_24.png b/vtm-app/res/drawable-nodpi/marker_poi_picasa_24.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f7e91b564dc1171ed8e13865540ff8881dcf5aa
GIT binary patch
literal 2295
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
P{GssR$RO1R`@Z-uiGZY-

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_poi_wikipedia_16.png b/vtm-app/res/drawable-nodpi/marker_poi_wikipedia_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..25cff18ca13aac209bb74afdfa95d76411b7b355
GIT binary patch
literal 1474
zcmb7EdrT8|96#f94k2U8Ts0fsj*_8B@6pn0Zxna-u3AQU6r#mA#<h1qp}p&_hkamF
zd<3diT!MeN=oB_XjBbo%3qkP};->R4m&HUuc|^%F9gvN&Ic0NqK+!*p$u7D3J@WZ{
zzVC|^<gHGKTM`EVK!SA*WtZ1P<()TI{w^JR!pO^FiFQauLb()RL=GTX!O4MEFH^zU
zIfe~=bcxFXfZ3()Vu$3g<q|Hzt6>z3Cg}CaYyikw8T2u(YEA;3T!ouAL8GV6LZF*9
zLF+PYh|Oo_D&1?sB3Bg7D|UseT}BpKnGI$I30c6)NemeDdU!t(G(nTPguGX-VF;Xr
zNYy52$|;Af05l6C2WD!J3>TtDKs~BKwK^QfSAZCTA~1r%D3*cZgcc(Z1e|^#*_z0f
z6L!inZA(6xph`*d5ilGG1T+DyMi47t)Mzv+8W@%#BQpFUUSfh7ygwzTKyiMT==Mo&
zfd>^u#wpZDCP?;lDg>|3W}6Y_{nLq(Qw9eaAB<`c*y~l|nne30JNML$=c4_^As+|Z
zIloXNy5xG4r^Lu|?p|z20m|MG`J!7c3ge*!SB;nBB`aluYHHjpLF#ZyN8?%?HybG$
zMGZ7%CP{<QVnNM#CT)%hJWG@%HLT3dMD;k18EML5F{3DrkOopu(nhV3q|LZdr;l;1
zykBB?7pE9ixbCN1>V;gwEOLw_h{b~7iIu;gQji3HrQie2MVa6_H_r+Izfzg0Kq*di
zZ{%2uD0soi)DrIJSVu_Afa5f!#Sk5hpy(=0i_@4{PwGgcmd+%hX)gP}(*?_(z)Dj*
z(<HGgx$~6mOv}rMnW5o$c~V4qBt8s#<vE@8$V!pL!Ja0&?f9`m)dy$px74O`&|=lT
z#`w>7)XiGBLuI%yu;<>Z4Y^mEnwyvUE;mK4l%^bwZ>md*sQ)&cY^dw17`<aUiT}K@
zvGvoy=$*$|4@zpk$Vl6tv+wfIzMP|paXTO8+~)CvKU5sdduQIolAD#f%~iTj-e`AB
zq;7pMzUzXsaDIKawdd{TtKrlCE}N?^U2_Hlh!QYy)5JsJdQZP6^^f=4>NaTV^IEsF
z*ee~qQD=L@csRPMdF$2k?Q4(k^yqhQJQW=hBNB1-tC52XBQNd!E+t)mAh&^ne$8zy
ztkWKdU$JQZ!mQ-R{#&<aomiVL5pOjdIe{k5dr!Tf*?z1nE4h2nhumoWY1x(Xu@vA?
zQq<CZhyT%|Z!TUw_*)QJ5-meiDo01}oY&sma<b;-flzYx;YQoBwa0U>mmwFW0mI%y
zzuXr)9mBJMgm2bI3(|I!w$)!^w{;H!5o%lb^xpGj=REo)(JjW`%Qh|F@2u|J@U73l
zj$E%E8VeZ?UCa0W(>MB8s3rUIjj9X19{u+px810k@aXSG=6B^Bbv|w+dd#&;`!uho
zFWNmQcAk4Mj-8*_yfP_n4vXEo`&mocy=!N`UO!xvAId)5&38OG5+8(A9lgU{LFmuN
urq#8}whQY0>Y>AtNALo5zPi6}jtUsrb^GSKsoA{pSGCf4)R(Kuw*3cY5*+aW

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_poi_wikipedia_32.png b/vtm-app/res/drawable-nodpi/marker_poi_wikipedia_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..24c77671b792eb8cef55a34dc4b480d39d971c07
GIT binary patch
literal 2117
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
Z&mF*YO@OVhP6j$JcBwcTu?ctN{~rqQOcVeB

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/marker_via.png b/vtm-app/res/drawable-nodpi/marker_via.png
new file mode 100644
index 0000000000000000000000000000000000000000..cbc2ca6252d2670476da100ea545caf791d8a778
GIT binary patch
literal 1119
zcmV-l1fctgP)<h;3K|Lk000e1NJLTq000yK001Hg1^@s6U#j`N000CgNkl<Zc-p0w
z3rv$&6vzLztCXS^QARA_)ZvgQLJ%1~n9K(_CL@}t!ABrd$c#>OiZ4W1GK~>mCCUt$
zLDxVeQ4<9vh!2tmYK;$qAVbB?;dBhG0&0-j;<?|0euWmDJ;}+v_uO-T-@W&od-4r{
zbNP&PHfady5W)76w3hS|X_KQx102{?q?<`sX}3ms2L*V;$J-OI0xhjC(9qP1wB33W
z&F7QuBJJo8IQqb*>H5JcnQubeS5W&!l1X9j(M^OW29%apqV<KjWn)fNG+F;}1Ps{u
z<K*iz!ZqrMImv)Uuv)33klV)875lfUig3~J=gSQ3^(i#0lLFoMq=nv_JkiHDGJ0Xp
zPV7F}jlM#2HPvTv+1UJF#-Uqd$<i*mXXR}T&Q4motjD+QX#>>5gPey<2JT*&oIF*G
zq^z5JshiG#BS?*ZolEfd(u{-E%6r|fyUMldp&sz|4Tel66Rv=VF+a{m<F?i&{91go
zV^_h05C%-lOwtr>NSP%ZLk>%OBkJpn@bk3dp@}zpDuI#g({CA!n95<4OkY6m5y;IS
z)?G%%k-t+IaIbEgW<%W9!7!U@=)zk#hu5!cr;9&0o@-0i)x$)Y=tnGkB00XB5A=5i
zVqs>pmH`XS{;Wt2A7!?SVrQ2<OcVwcMLE!BuWbhAZpSeOJa%e3k|I9mCoFU=a#C~W
z`+*9ju%?R#ewWPy_aFKJ>*FRl52*CWkJ|ywkiI^Zl!f1Gk;{Nf(ifm`WsJQ8%jMo;
zw!o<zucUW)0;vq>OM1<a1C3hEN0GZ9$&2gk79vY(mGLbXl(&4#0{D9+I&#k-Oib+T
z?4`(>|E0~bgJLvTVZTuPSdR#iE;Rxf$FYyP8%5xtwF$TrItKm|N5byCN+a(`?*0Q@
zZN$I1C14kAk`{-+)!(8zG7w$?BWy+)?b2$twNl%oXB3RvXg_=oQQ+%jpYj#9>Ko|i
zML?w%BPkwJn#g2({f6GK0bTiJToKlbQ;rJkVuGGXoWTz)<RS02wW1VP(Q_-oYU<`m
z7drwn(d}H0Ws!l7CmS9EYw~b~x-)yvIRlPLjYWN2I8@^El8HyA;GCr0<(Fd`jjBHs
z$Yjr!MM#h8RT5cL*Z+o6>c%@-)F04)#cVXjPlda*{GXvc6<kCtjV}COAd^CEDwg<t
z$`4p%m*;Tl5#nsY`+)N)H%~_k%NwYo?9kyC>Slf{aQKQCJe)HLDwfC<RJjVuFqQ0v
zj|DQ(>wdy?1x2}{2G5UPfIrz@xdJ>$<t>ffW7-i^&^V?)=MMp<Bt|3O%bi|E8DCLc
z1;)gNqFheE^9HP>@ljWSVdH}oH<WH>+^FG>Tj45@{bDo<zU=SG=qiw<^#f850e;_A
lpd0CJQo2P<AZ_c<`5h9^OrL&42&(`9002ovPDHLkV1njL9<l%c

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-nodpi/pin.png b/vtm-app/res/drawable-nodpi/pin.png
new file mode 100644
index 0000000000000000000000000000000000000000..46c70185a9cce81511db93eaa2a518d00b4fdef6
GIT binary patch
literal 1725
zcmV;u215CXP)<h;3K|Lk000e1NJLTq000>P001cn1^@s6z>|W`00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru+zS*IGc~*L`TPI?21-dp
zK~z}7m6uy+T-Ozbzq8Moqmf3Vk;k6eR_sP8O>aTa2lb&3eTm}Oy}URLgqqTnQc@D=
zlW^_SZS9n%QR^ZiY^M+i2nr!3c3O<x1`Ngurb!3|#{mi17F8UC6pb!3n)^9>@70Hy
zk!L)*jQ3$N=d#!Q`(NwdYn|f^zVvU}9WP%v_GKVZyPQ7p!$0Le`rV;z{hYy<{<X!Q
z9!~;41r7lRI+Vh#Ju6#_g$3Xu@aB^re>|}{$f;J4KU_HG0!M)psaUMrOD6Gpdt2s7
zr9!y6N?~=Cyw>jmzdCsH<|i9~T)q$BcoKLk)!BK#-?tCt``94B77DE^^nKh|41i#M
zp3hfSO2AJJ-n@Cfah?(p>UQ${v1BOnpHye(foOj}7(=+cjLGE?Yg^2g%Y@6z=+#yH
z-MiWQ&_kWQp7-{pfr00nK<X!_E*y7(xBI%fzS{Bd!{}@loy#G{Y-=_Q36_>{V==n=
z`T)*c8W?!|9*78t036-p`;T|*-;d5@u$2l}+hQsb+3-Hr5-u;JqEYtk+T{XoT^blj
zR>OsG>YW#pz=@8%dohIqwp?ynsp{y!>+P*3-*MK@y+opgRj{~-*W1h9&dyX#JSYS#
z97#nY-HzvBa=E6}MUqJz->34~XM8#{gURLibY_Ok>?}H)C6Y{5W76Pb3I+T<d$91_
z#eo4=QBC?Y9f?FWL=D4@$I-bQcV}nW_0&@woS5L7@4d(OZrtE&Cr?tyW(nr!?*Y|@
zEf#T<BJR3L5&5?B&&M9?1~Omj?{~v=x@mGGl_EPg$D_l;eBsEE773STX1M<J)9mT%
z!<Ng~VzJ4$GC$8;rSh_}@WrT7t{6k3oSjGnQz#IN#Wn=MS~?$jgs&VvOt83!ibk9K
zO`%ZTWAF_HBpt_TiK~i6F}WP^!NCmy0K^#LgM(zWZt+J1lmbY276K7LjKNf;T+N5p
zh)7GG8Ue5tQ!3#)PK&>?7PQ7fNda@^I(ow}#Ufr$59tp-M8dGSX4NGt!s?YP#9g-v
z+E{Xw!d4m1DI>B_5y?w!6-ERjLZCG$g%;uNE3Y)MsQ+fJUS;-!5Ab?>G1=_8uMq*)
zrD!ci<gR=BXXoTQx2}CFuJzabc$`YPi~v##Su_@7?#2zu*RJ9B_2H*dly2W<VSJpA
z#>PnbK5isJu~b_3!*TF^pM`uL1HbfYYB-w?!^3^m9<e?OVMxqcb|w;J?%ZMKg%>DW
zOT=+VMk4G_Bye1pwQRO2RPpX^3TtbWt-bQh<m9A6gg^e^<kdB;-w*P6;<4EJiUi0T
zLm`)=tGk>1J9hBs&Ykoplk~*nNTtGBF4r`_p8BOAz{2kVynDAfy`uFyyG5`KDgm%S
zW^Jvl7M+O2DCYANt-boA$;s<Y{lth|Tn@uKx?Cpix=l%Z5W`xQf&e2j(o*XG{Qch=
zV01YQQJ#mbF?bN$5s6T$RLB|g-ycs+U1{iythW>k<LNL=TdnC*s;Nx0V<^RP7-C_h
zxidDPoc``_N&>Hc9)?7fLPOiu<9QUqkX5ax1^%&VkFRaWv86C9Ss?lVY$A@sYPB+q
zJUcaI?(6Z*0z7@_*J<Ey=`f^QskRi=<9QUVC1cE8;LZD=H-)QiR%CQB2uyurZl|a^
z3oA1E?9^1y0<sbHzZ`sV+K61vXw8mDgivHtiz-DRLOKl7M&yl+m~O}f5iE?Z)XV)A
zvW>YeD^*3E{rU8CenXJW68Y+r$0rKLyk9Ve-M+u!oS5rkfOHt<fw9eU){^-9s?gX<
zt?O;XqT6*@sw(QQ&rMHfHwW1yT!<iWe$ALWWn)NsUXx=~DXa)fVHgOEZlyl8mG)nK
z;;6AAV=G$YDb=K?9?z@pZjtd{OiwRt39@y#1YkU)by{0X+;y=)#Bq?Sq73(ykWHAd
zRm2#3;%FXtJ)<?9u8Y(PVJ%mGfBx33|7{Dxb|_T|pIy>AFd{^2EHc$Mk&$*PLL1={
z&I}DNh{*Vw*7SHDSz`#Sy?kb9_>=ZPw#T6MQa+Y3rrIUzETp{;S|zl1oEsXRtXO-o
zU<_qzC(aEGUzavf+RDlLz7ZMCR7=fB!^cxQIca~qHZ(j@GUkofhKApL5WoKeM3sGj
T{S(|)00000NkvXXu0mjfoL5k6

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-xhdpi/ic_action_search.png b/vtm-app/res/drawable-xhdpi/ic_action_search.png
new file mode 100644
index 0000000000000000000000000000000000000000..d699c6b37e0dcb1d636ebdd6733ab6d576d97ab5
GIT binary patch
literal 3199
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
ReC-u>pr>W5S)<|b@_%^e3*P_$

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-xhdpi/ic_launcher.png b/vtm-app/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..436ec1cc2d3be22d0fbaa5d0867ace28c4e87399
GIT binary patch
literal 4591
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
Z=l_*8DYSXK3$g$J002ovPDHLkV1j?dsM!Dj

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable-xhdpi/ic_layers.png b/vtm-app/res/drawable-xhdpi/ic_layers.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb2ba471e346ba0feae5eccb9b84c7c8ea7525d5
GIT binary patch
literal 4940
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable/arrow.png b/vtm-app/res/drawable/arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..8cb329881410f83c6221b07353ff0c1634b3fd49
GIT binary patch
literal 10033
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
Hu0mjfniUB<

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable/bkg_compass.png b/vtm-app/res/drawable/bkg_compass.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ee7e7b9c319db6343e85bf3865001f5b599bb5d
GIT binary patch
literal 40821
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

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable/btn_delete.xml b/vtm-app/res/drawable/btn_delete.xml
new file mode 100644
index 00000000..98cf83ba
--- /dev/null
+++ b/vtm-app/res/drawable/btn_delete.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/delete_pressed" android:state_pressed="true" />
+    <item android:drawable="@drawable/delete" android:state_focused="true" />
+    <item android:drawable="@drawable/delete" />
+</selector>
diff --git a/vtm-app/res/drawable/btn_moreinfo.xml b/vtm-app/res/drawable/btn_moreinfo.xml
new file mode 100644
index 00000000..106072e3
--- /dev/null
+++ b/vtm-app/res/drawable/btn_moreinfo.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/moreinfo_arrow_pressed" android:state_pressed="true" />
+    <item android:drawable="@drawable/moreinfo_arrow" android:state_focused="true" />
+    <item android:drawable="@drawable/moreinfo_arrow" />
+</selector>
diff --git a/vtm-app/res/drawable/compass.png b/vtm-app/res/drawable/compass.png
new file mode 100644
index 0000000000000000000000000000000000000000..7056bcfb266d02c059711f62efe2fcdf31b5f51d
GIT binary patch
literal 1826
zcmV+-2i^FIP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU&#7RU!RCwCVTa9_5KoG?=fE`E&*a3Ec
z9bgAu2V4iH19KIaRDh{KQvs#|k_tE;neoPTl?4XQ{k}bt3(U^E`DJ#Qcq5FmEW_$D
zuVz5k>5W^zs(GyD3D?PF@-Z}TlYs>GtILw+0s`;%d+&5Q)${A?%R3&A7thS+b8kAG
z))PN377PB<Yc=<{R)BnZk31^DqiXJ|Sso6Da=l)cVHlS9Q<sTnK?AgCWYtU_&H{+3
z-<4*A=jUhd<>kfu{In}8ilX`|G+Yl@2nH<U`}_Oqx!G*ytyZgg20;K9`CVDWpGVO6
zA<y$NNs=oKR!rCbzuWCf+#^PIV;1-$?!`0EK4_S9L6hj=pXh%G?pJeD6h)b)sg=Pj
z%UD?0Z%SbKEr3l4l-dPA)A#+0bpQ}}Ah+|!5<Ud-5Kw9d%mEBy2%1?}bEX7#0vs4{
z2?TzIwUG5hLkkZ^3RCOQ4hfzO$pl$OhP9x5(;8?bg9(p?<2b(XaWeH{u!U~}k;64)
zmch@Yi0vT4%f$c$FE*P0-H1an0IP#w6Q0bim)3=E_lgx{4aH`&(FegM{C2x#;lrMR
zv=C`ggWdtWSwKj7F)4jsLwKTn;CLcjDOYfbD-dWzoruY34?j~9J_aER?cNcb`Ihb=
z+|_SGXoCpLM5^+Y84ML-N^M4F4Z#JCQk_!Bz(|>D*M`8ELBU+26uAo&E@t&e?o}!k
zPce9A8E_>TBA16VX`Zdnb1S5*?+u6rG}cOMZNR(X3VCBn0a9FQ5>tg%o(GVUzB%ay
z=b%_8<g#KU`iZml8y{%L(5z0(B1)SR!AmRF*c3{^Hoxin&Np{srnW(uR&5Os8XLuR
zZAy);(OGIoQ~R9zL9?j~MBN`v;4iEIU|3@se4Q&k@_kJvYSqg8d~1rgx>yr@4!p<+
zSJ?)ON$t@4wWb-?&h6446bx=P-A~pvWM#>P`LlLlDw=_a=;xAwrYRa6zG6l=*9Bx{
zwHrLqJqvD1QnT`;)srVv4$vrd9j~wGgx7lqOO?*=WP&d1o*S_w>*4|(4ic1#G|lg-
z^lh4&rLo{6l|lY&<%p8f|Ecmz6iv@s`Zi6?(wMV>O-{JL9J@6<$V`q(z{7;6WYVpM
zcxI`@%P|Oo^DiWG005@EO@++|@)@l?xh1y2x&ZL@_Qp)E6yv~oV@3iHfXVtdfsjV&
z3jiRzZKtP&70eYg(%$&}2Y`l~`j~$w?eh?sW2L1SRx(@t(}0cJ70e8#+;x0>d@!R+
zZ2;Kn2LXW31N70pVFiI^X)K2gfT@P|4HND>w6g)5KF%R90A|XYYxqAFf(iE>*k&gX
zmKvoon?4R<FaTeShIwjZtkQSH(s;oDa5+%->16M$Qy;x&={rVg%pED?g)2Qb3^YpN
zKBe!_r7<ki@=6>(RTa`ZT%bZ(y1`=X(szVlxR5SRG2nRam~gMIPdBKk>)Uts=^D$f
z5N-4n7abe<s!0A8cJZ-$UEjX5YuA{0GhX?3H(O%lZ`+oOG<JPG%UL4ZCW&^}7`(~2
zbk!2$rYKB9nn;_x`*XM}cNScp8oPDMOsi{*`z=jT|Eh7>wJq-2^)&=9=p<M|hpL=_
z5MATQk+(!D=4Qvs^b_6~aj^nArBSj4ISTHZjJg0JcB<31+86aibnE7eT@*66v?~BE
zg4;B94~RAZnA)dJk;7d<WEvB(VCE8K0T>p+Y%6#Z5KLE`8xCEHG7ic@`*C9~m$86+
zCUaz1j=YQD_ka+?Mf*D$`APekYtB4p1RzJ+bXn9VcTn3@F#>JmQVR3oF1BQmK10{V
zQV1;xXq^%ndT>UP@rc}J)0R*sT|w)R)Cj^~oDU)wKD2g44kD7+BZI)gtDbCQbCTt)
zAeua~@WO55zQnIii;C0X=>rJAHV<B@$1DcHT!gYirnP_9!9{nbas~_7wj*xH5)@<#
zjhx?7>viWz_8zoOoHqIzvV&Y0DTi8V{H2IL(E16#b(&?jP((b2>18%1paIIc1vN)Q
zCD0*VVS6`#$<vyLQL_`9A*{jd00S8OKlvhqv37ZdrD`vsXL8U0EfZ|ve*Z5RQ`x-Z
zkC|+(a4?R)!9@rV`L4j9%l&(Es_wzPc*fRUGCt1g9e}kyoP=h7p<{~;5p;0xZHn?9
zy*b|B-|s%dA5MBdJJ|Se^8L}Ou^Ia-n=X8|%O(k)fdzmDrCYVQqHY0qtb#wDp7RIO
z`~kIXVCx!_KcuF<J+!^AwEZ>&pOX=-1AqkHzXKWO=F6V0K<6};dH)q)03QKpN2EZ=
QkN^Mx07*qoM6N<$f~7iJa{vGU

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable/globe2.png b/vtm-app/res/drawable/globe2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d788024b03350e799951cc58809c36ee88b905c
GIT binary patch
literal 6256
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
aJo`V`RkX|Juz#xn0000<MNUMnLSTaVoY_kN

literal 0
HcmV?d00001

diff --git a/vtm-app/res/drawable/person.png b/vtm-app/res/drawable/person.png
new file mode 100644
index 0000000000000000000000000000000000000000..9f9db93eab6f0548198db9cd2c9dc16d54296ef3
GIT binary patch
literal 1531
zcmV<X1qAwuP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H11$aqBK~!jg?U_q#RAm&$e`n^-bUJ+uQd(LBM2QLtY6wa~e6W#_
zXkyrz5LT{SXtX98Bre^NurLu9#6;slBaxUGbfE@Rq6Whw5=0P0EEH&`kLkSc<GA>~
z+nK%~b}p?ZJ;}+JJNMr2{Quv1eCK{6s>=UaV)G54QCT1`-?Bj9W+EcXMP!|bIJe72
z<OD=SlF9f>>2zu&lS%)+tf%8>GT{{3+fxTbq$6s3sA{B|$+RBWxZ(b>-%h-zI`)a`
z==+-Q+oQcNK2c6LI|D#xl=dXbeZX;?=U1-i+<)emy)CIk6@okj1@H?H6xj9lH`RR~
zoIWx#THP9z%}5D!bhIDc|IQ1Ww?DHMd<(vgfLqPcw&tK)sRmuDIueD=NOPc4sXVx0
zT|0P#;AM@vS$jQ5LWj9`RjLF$6qU_L2_zHo!M?vQ*T7rgwd*YXH!2R$AC=8W33#6O
z?WYHiS8J=DouJ1~UZq$HT;Pw$j7C`zfW<9oXYixFkEmYQqI&*O)w2(%p1DiUA6le6
zostKh`%hIN5m^tc1}*`sfP30n;%_{>wyFKur&6g*i_5WJOYX;CdV%Zmq3d%9xB_$l
zWmP@gko`soh{%?<mZmQ@ZM@t2@z}-GqD-r-U9++j1U}bq3@1v(yrY39PBP_nb)>!K
zR4gc0DzQ_iuQjh&s^y^^GFIT-d{JMY7XqndV$bg0r(b*P)yH}H&4YU8LRr54tQUe3
z1ZB{v<FS)h*}CH^vPa<DU+~xtvblmTnJtEfdz3`H3VxQRgbV6|H(<e*4Ux&CH;fZU
zV=*Mv)Ts3c2oMy(8?vCQrus|<T~8>8Wd9nM1_=ZvJp3UuY5@MA0X${(Z7BJ<Xpmcp
z#shxn0Wlt!F8)IzULgY5HHj{Sv<w=b7($bYXcZzpLufpNf)e<y1(~!2CdEB|Bw(kL
z#yy}#@I6z36q^G!T;@O~5D*ao;`Vn3(<_O+?E{`2eN_zr3)ViNF8IT90J|m*fQZC_
zB+v>hvf2iu>@xvS2F8F9U_?a5niAvWtjzr(nPWe=TY*lX2UrTUV+h5mc_09)7!o&t
zKKsnPN*E>y%xbp+X`rd@9+;&S4B%#<1>>dk9OIoLF-%<NfUCfH;2fs2yp9Q%0w#Pa
zcC2CuF82c3zdMe5_D}f!IGRjMoV<S!cI+ak|1FV#d<i*q4vwA#g;FB~990cOq-sf&
zfnkg%GFIC$E1t%9pv`K`_xb6E6Rh8~lWyOq)Vq`J`pE}|;Pb;14R)J@mGb7DR3%2a
zP-1&S1VkhZp;k<fz67{~S`sHPxe#h70(fHu_Sx%gu^8LxC(oClP$K3B5U>08iwV_2
zNi&TAAD;^o-(if0L>61kFfk{jPH$Oq@<lU_j!n5Gw(>PBj;gANxR?;~FfmyGx-p5G
zqE?MU&>@MNN=RTh2aD_0+fI@ck+L@UN$3FBNva~^Ve%k{$%P(Fc@4|zOosr|f(QwW
zO!WYO+bDRLv=iHeu3$V-1V%ALmSOUv1ruiB>eqW@isWs5nSp>KBEk5M9t8my_l74T
zVe62`l+$jEH(Kl7i(?2mOyh-{cpwJc31mg22zaw4GGjA0O;}|y2_1SMj`2vR)hR9K
zSiuyB83^2mIi0u$jEYEgHX(J(Zq%+!1*nKfj#{{cJM#dh{TQA6?nn;b5|~_Z6tgIS
zohNJ>|22Uq&V>?~_F{K;2e0&W;aV_Ux`H#Dqrazvo}Ml$fVv)Xp^r+j#A?8`>d!Wz
zBRQS6ZFn2-B(;45%qss3tP6o+R{gT7UToMf5g)HxA~9;^Hc-{u_c=zy1m;5){-vC6
hSs*aqvOr+I<sXMcqVh;Ym)rmV002ovPDHLkV1kHCx4r-X

literal 0
HcmV?d00001

diff --git a/vtm-app/res/layout/activity_file_picker.xml b/vtm-app/res/layout/activity_file_picker.xml
new file mode 100644
index 00000000..b47fa3b5
--- /dev/null
+++ b/vtm-app/res/layout/activity_file_picker.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<GridView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/filePickerView"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:fadingEdge="vertical"
+    android:fadingEdgeLength="30dip"
+    android:columnWidth="100dip"
+    android:numColumns="auto_fit" />
\ No newline at end of file
diff --git a/vtm-app/res/layout/activity_tilemap.xml b/vtm-app/res/layout/activity_tilemap.xml
new file mode 100644
index 00000000..489be4ce
--- /dev/null
+++ b/vtm-app/res/layout/activity_tilemap.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/mainView"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:windowActionBarOverlay="true">
+
+    <org.oscim.android.MapView
+        android:id="@+id/mapView"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" />
+
+    <RelativeLayout
+        android:id="@+id/route_bar"
+        android:layout_width="fill_parent"
+        android:layout_height="25dip"
+        android:background="#dd000000"
+        android:orientation="horizontal">
+
+        <ImageView
+            android:id="@+id/route_bar_distance_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/plane" />
+
+        <TextView
+            android:id="@+id/route_bar_distance"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_toRightOf="@+id/route_bar_distance_icon"
+            android:gravity="center"
+            android:textColor="#fff"
+            android:textSize="14sp" />
+
+        <ImageView
+            android:id="@+id/route_bar_route_length_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/route_bar_distance"
+            android:src="@drawable/car" />
+
+        <TextView
+            android:id="@+id/route_bar_route_length"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_toRightOf="@+id/route_bar_route_length_icon"
+            android:gravity="center"
+            android:textColor="#fff"
+            android:textSize="14sp" />
+
+        <ImageView
+            android:id="@+id/route_bar_travel_time_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/route_bar_route_length"
+            android:src="@drawable/time" />
+
+        <TextView
+            android:id="@+id/route_bar_travel_time"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_toRightOf="@+id/route_bar_travel_time_icon"
+            android:gravity="center"
+            android:textColor="#fff"
+            android:textSize="14sp" />
+
+        <ImageView
+            android:id="@+id/route_bar_clear"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:clickable="true"
+            android:src="@drawable/no" />
+    </RelativeLayout>
+
+    <ToggleButton
+        android:id="@+id/snapToLocationView"
+        android:layout_width="57dp"
+        android:layout_height="72dp"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:layout_marginBottom="10dip"
+        android:layout_marginRight="10dip"
+        android:textOff=""
+        android:textOn=""
+        android:visibility="gone" />
+
+    <TextView
+        android:id="@+id/mapInfo"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="left"
+        android:layout_marginLeft="70dip"
+        android:layout_marginTop="25dip"
+        android:background="@drawable/info_window"
+        android:clickable="true"
+        android:ellipsize="end"
+        android:maxEms="17"
+        android:onClick="onClick"
+        android:textColor="#404040"
+        android:visibility="invisible" />
+
+    <!-- android:background="@drawable/snap_to_position" -->
+
+
+    <!--
+          <ImageView
+         android:id="@+id/imageView1"
+         android:layout_width="64px"
+         android:layout_height="64px"
+         android:layout_alignParentLeft="true"
+         android:layout_alignTop="@+id/mapInfo"
+         android:src="@drawable/compass_bg" />
+    -->
+
+    <ImageView
+        android:id="@+id/compass"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_alignBottom="@+id/mapInfo"
+        android:layout_alignParentLeft="true"
+        android:layout_marginLeft="24dp"
+        android:onClick="toggleLocation"
+        android:src="@drawable/compass" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/vtm-app/res/layout/bonuspack_bubble.xml b/vtm-app/res/layout/bonuspack_bubble.xml
new file mode 100644
index 00000000..d7b154e6
--- /dev/null
+++ b/vtm-app/res/layout/bonuspack_bubble.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_margin="10dp"
+    android:background="@drawable/bonuspack_bubble"
+    android:orientation="horizontal">
+
+    <ImageView
+        android:id="@+id/bubble_image"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:paddingLeft="5dp"
+        android:paddingRight="5dp"
+        android:scaleType="center"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="0.5"
+        android:orientation="vertical"
+        android:paddingLeft="5dp">
+
+        <TextView
+            android:id="@+id/bubble_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="left"
+            android:ellipsize="end"
+            android:maxEms="17"
+            android:textColor="#404040" />
+
+        <TextView
+            android:id="@+id/bubble_description"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxEms="17"
+            android:textColor="#404040"
+            android:textSize="12dp" />
+
+        <TextView
+            android:id="@+id/bubble_subdescription"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxEms="17"
+            android:textColor="#404040"
+            android:textSize="10dp"
+            android:visibility="gone" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:orientation="horizontal"
+        android:paddingLeft="5dp">
+
+        <Button
+            android:id="@+id/bubble_moreinfo"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:background="@drawable/btn_moreinfo"
+            android:visibility="gone" />
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/vtm-app/res/layout/dialog_enter_coordinates.xml b/vtm-app/res/layout/dialog_enter_coordinates.xml
new file mode 100644
index 00000000..23b2d555
--- /dev/null
+++ b/vtm-app/res/layout/dialog_enter_coordinates.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="20dip">
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/latitude"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <EditText
+            android:id="@+id/latitude"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:maxLength="9"
+            android:inputType="numberSigned|numberDecimal" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/longitude"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <EditText
+            android:id="@+id/longitude"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:maxLength="9"
+            android:inputType="numberSigned|numberDecimal" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/zoomLevel"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <SeekBar
+            android:id="@+id/zoomLevel"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" />
+
+        <TextView
+            android:id="@+id/zoomlevelValue"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textStyle="bold"
+            android:gravity="center_horizontal" />
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/vtm-app/res/layout/dialog_info_map_file.xml b/vtm-app/res/layout/dialog_info_map_file.xml
new file mode 100644
index 00000000..8689fee0
--- /dev/null
+++ b/vtm-app/res/layout/dialog_info_map_file.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="20dip">
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_name"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewName"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_size"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewSize"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_version"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewVersion"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_debug"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewDebug"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_date"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewDate"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_area"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewArea"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_start_position"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewStartPosition"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_start_zoom_level"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewStartZoomLevel"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_language_preference"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewLanguagePreference"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_comment"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewComment"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/info_map_file_created_by"
+            android:textStyle="bold"
+            android:textColor="#FFF" />
+
+        <TextView
+            android:id="@+id/infoMapFileViewCreatedBy"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="10dip" />
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/vtm-app/res/layout/item_layout.xml b/vtm-app/res/layout/item_layout.xml
new file mode 100644
index 00000000..3c4e029a
--- /dev/null
+++ b/vtm-app/res/layout/item_layout.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal">
+
+    <ImageView
+        android:id="@+id/thumbnail"
+        android:layout_width="65dp"
+        android:layout_height="65dp"
+        android:scaleType="center"
+        android:src="@drawable/ic_continue" />
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="instructions"
+            android:textColor="#000000" />
+
+        <TextView
+            android:id="@+id/details"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="distance/duration"
+            android:textColor="#555555" />
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/vtm-app/res/layout/items_list.xml b/vtm-app/res/layout/items_list.xml
new file mode 100644
index 00000000..6a74bf69
--- /dev/null
+++ b/vtm-app/res/layout/items_list.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="#55000000"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center|clip_vertical"
+        android:layout_marginBottom="10dp"
+        android:layout_marginLeft="10dp"
+        android:layout_marginRight="10dp"
+        android:layout_marginTop="10dp"
+        android:background="#FFFFFF"
+        android:orientation="vertical"
+        android:padding="10dp">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <AutoCompleteTextView
+                android:id="@+id/poiTag"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:completionThreshold="1"
+                android:ems="10" />
+
+            <!-- 	<Button
+                    android:id="@+id/buttonSetPOITag"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Search" /> -->
+        </LinearLayout>
+
+        <HorizontalScrollView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="40dp"
+                android:orientation="horizontal">
+
+                <Button
+                    android:id="@+id/pois_btn_nominatim"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Places" />
+
+                <Button
+                    android:id="@+id/pois_btn_wikipedia"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Wikipedia" />
+
+                <Button
+                    android:id="@+id/pois_btn_flickr"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Flickr" />
+
+                <Button
+                    android:id="@+id/pois_btn_foursquare"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Foursquare" />
+            </LinearLayout>
+        </HorizontalScrollView>
+
+        <ListView
+            android:id="@+id/items"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent" />
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/vtm-app/res/layout/itinerary_bubble.xml b/vtm-app/res/layout/itinerary_bubble.xml
new file mode 100644
index 00000000..29311e76
--- /dev/null
+++ b/vtm-app/res/layout/itinerary_bubble.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:background="@drawable/bonuspack_bubble">
+
+    <ImageView
+        android:id="@+id/bubble_image"
+        android:layout_width="65dp"
+        android:layout_height="65dp"
+        android:paddingLeft="5dp"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/bubble_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textColor="#404040"
+                android:maxEms="17"
+                android:text="Title" />
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/bubble_description"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="#404040"
+            android:textSize="12dp"
+            android:maxEms="17"
+            android:text="Description" />
+
+        <TextView
+            android:id="@+id/bubble_subdescription"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="#404040"
+            android:textSize="10dp"
+            android:maxEms="17"
+            android:text="Address"
+            android:visibility="gone" />
+    </LinearLayout>
+
+    <Button
+        android:id="@+id/bubble_delete"
+        android:background="@drawable/btn_delete"
+        android:visibility="visible"
+        android:layout_width="25dp"
+        android:layout_height="25dp"
+        android:layout_gravity="right" />
+</LinearLayout>
diff --git a/vtm-app/res/layout/seek_bar_preference.xml b/vtm-app/res/layout/seek_bar_preference.xml
new file mode 100644
index 00000000..4dd6ae4e
--- /dev/null
+++ b/vtm-app/res/layout/seek_bar_preference.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/widget_frame"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:paddingLeft="15dp"
+    android:paddingTop="5dp"
+    android:paddingRight="10dp"
+    android:paddingBottom="5dp">
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:textSize="22dp"
+        android:typeface="sans"
+        android:textStyle="normal"
+        android:textColor="#ffffff"></TextView>
+
+    <TextView
+        android:id="@android:id/summary"
+        android:layout_alignParentLeft="true"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@android:id/title"></TextView>
+
+    <TextView
+        android:id="@+id/seekBarPrefUnitsRight"
+        android:layout_alignParentRight="true"
+        android:layout_below="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"></TextView>
+
+    <TextView
+        android:id="@+id/seekBarPrefValue"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_toLeftOf="@id/seekBarPrefUnitsRight"
+        android:layout_below="@android:id/title"
+        android:gravity="right"></TextView>
+
+    <TextView
+        android:id="@+id/seekBarPrefUnitsLeft"
+        android:layout_below="@android:id/title"
+        android:layout_toLeftOf="@id/seekBarPrefValue"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"></TextView>
+
+    <LinearLayout
+        android:id="@+id/seekBarPrefBarContainer"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@android:id/summary"></LinearLayout>
+
+</RelativeLayout>
diff --git a/vtm-app/res/menu/map_menu.xml b/vtm-app/res/menu/map_menu.xml
new file mode 100644
index 00000000..86438ec8
--- /dev/null
+++ b/vtm-app/res/menu/map_menu.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/menu_poi_nearby"
+        android:title="@string/menu_find" />
+    <item
+        android:id="@+id/menu_route_departure"
+        android:title="Set Departure" />
+    <item
+        android:id="@+id/menu_route_destination"
+        android:title="Set Destination" />
+    <item
+        android:id="@+id/menu_route_viapoint"
+        android:title="Add Via-Point" />
+    <item
+        android:id="@+id/menu_route_clear"
+        android:title="Clear Route" />
+    <item
+        android:id="@+id/menu_poi_clear"
+        android:title="Clear POIs" />
+</menu>
\ No newline at end of file
diff --git a/vtm-app/res/menu/options_menu.xml b/vtm-app/res/menu/options_menu.xml
new file mode 100644
index 00000000..1ceb16c7
--- /dev/null
+++ b/vtm-app/res/menu/options_menu.xml
@@ -0,0 +1,106 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/menu_position"
+        android:icon="@drawable/ic_menu_mylocation"
+        android:showAsAction="always"
+        android:title="@string/menu_position">
+        <menu>
+            <item
+                android:id="@+id/menu_poi_nearby"
+                android:title="@string/menu_find" />
+            <item
+                android:id="@+id/menu_position_my_location_enable"
+                android:checkable="true"
+                android:title="@string/menu_position_my_location_enable" />
+            <item
+                android:id="@+id/menu_position_follow_location"
+                android:checkable="true"
+                android:title="@string/menu_position_follow_location" />
+            <item
+                android:id="@+id/menu_compass_2d"
+                android:checkable="true"
+                android:title="@string/menu_compass_2d" />
+            <item
+                android:id="@+id/menu_compass_3d"
+                android:checkable="true"
+                android:title="@string/menu_compass_3d" />
+
+            <!--
+                       <item
+                      android:id="@+id/menu_compass_enable"
+                      android:checkable="true"
+                      android:title="@string/menu_compass_enable"/>
+            -->
+            <item
+                android:id="@+id/menu_position_enter_coordinates"
+                android:title="@string/menu_position_enter_coordinates" />
+
+            <!--
+              <item
+              android:id="@+id/menu_position_last_known"
+              android:title="@string/menu_position_last_known"/>
+            -->
+
+            <item
+                android:id="@+id/menu_position_map_center"
+                android:title="@string/menu_position_map_file_center" />
+        </menu>
+    </item>
+    <!--
+      <item
+      android:id="@+id/menu_options"
+      android:icon="@drawable/ic_menu_options"
+      android:showAsAction="always"
+      android:title="@string/menu_options">
+      <menu>
+    -->
+    <!-- android:icon="@drawable/ic_menu_preferences" -->
+    <item
+        android:id="@+id/menu_preferences"
+        android:icon="@drawable/ic_menu_options"
+        android:showAsAction="never"
+        android:title="@string/menu_settings" />
+
+    <!-- android:icon="@drawable/ic_menu_mapmode" -->
+    <!-- android:icon="@drawable/ic_menu_archive" -->
+    <!--
+      <item
+      android:id="@+id/menu_mapfile"
+      android:showAsAction="never"
+      android:title="@string/menu_mapfile"/>
+    -->
+    <!--
+      <item
+      android:id="@+id/menu_info_map_file"
+      android:title="@string/menu_info_map_file"/>
+    -->
+    <!--
+      </menu>
+      </item>
+    -->
+    <item
+        android:id="@+id/menu_info_about"
+        android:icon="@drawable/info"
+        android:title="@string/menu_info_about" />
+    <item
+        android:id="@+id/menu_layers"
+        android:icon="@drawable/ic_layers"
+        android:title="@string/menu_layers">
+        <menu>
+            <item
+                android:id="@+id/menu_layer_naturalearth"
+                android:checkable="true"
+                android:title="@string/menu_layer_naturalearth" />
+            <item
+                android:id="@+id/menu_layer_openstreetmap"
+                android:checkable="true"
+                android:title="@string/menu_layer_openstreetmap" />
+            <item
+                android:id="@+id/menu_layer_grid"
+                android:checkable="true"
+                android:title="@string/menu_layer_grid" />
+        </menu>
+    </item>
+
+</menu>
\ No newline at end of file
diff --git a/vtm-app/res/menu/poi_menu.xml b/vtm-app/res/menu/poi_menu.xml
new file mode 100644
index 00000000..3d5f13d0
--- /dev/null
+++ b/vtm-app/res/menu/poi_menu.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/menu_link"
+        android:title="Open URL" />
+    <item
+        android:id="@+id/menu_none"
+        android:title="Cancel" />
+</menu>
\ No newline at end of file
diff --git a/vtm-app/res/values-v11/styles.xml b/vtm-app/res/values-v11/styles.xml
new file mode 100644
index 00000000..d408cbc3
--- /dev/null
+++ b/vtm-app/res/values-v11/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
\ No newline at end of file
diff --git a/vtm-app/res/values-v14/styles.xml b/vtm-app/res/values-v14/styles.xml
new file mode 100644
index 00000000..1c089a78
--- /dev/null
+++ b/vtm-app/res/values-v14/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
\ No newline at end of file
diff --git a/vtm-app/res/values/poi_tags.xml b/vtm-app/res/values/poi_tags.xml
new file mode 100644
index 00000000..4e016bc7
--- /dev/null
+++ b/vtm-app/res/values/poi_tags.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+    <!-- OSM tags relevant for a Nominatim search by feature -->
+    <!--  See http://wiki.openstreetmap.org/wiki/Map_Features -->
+    <!--  in comment, those with 0 match for Paris area on 16/07/2012 -->
+    <string-array name="poi_tags">
+        <!-- Aeroway -->
+        <!-- <item>aerodrome</item> -->
+        <!-- Amenity -->
+        <item>bar</item>
+        <item>cafe</item>
+        <!-- <item>fast_food</item>  -->
+        <item>pub</item>
+        <item>restaurant</item>
+        <item>library</item>
+        <item>school</item>
+        <item>university</item>
+        <!--  <item>bicycle_parking</item> -->
+        <item>bus_station</item>
+        <!--  <item>car_rental</item> -->
+        <item>car_sharing</item>
+        <item>car_wash</item>
+        <!-- <item>ev_charging</item> -->
+        <item>fuel</item>
+        <item>parking</item>
+        <item>taxi</item>
+        <item>atm</item>
+        <item>bank</item>
+        <item>dentist</item>
+        <item>hospital</item>
+        <item>pharmacy</item>
+        <!--  <item>veterinary</item>  -->
+        <item>cinema</item>
+        <!--  <item>nightclub</item> -->
+        <item>theatre</item>
+        <!--  <item>fire_station</item> -->
+        <item>marketplace</item>
+        <item>police</item>
+        <!--  <item>post_box</item> -->
+        <!--  <item>post_office</item> -->
+        <!--  <item>recycling</item> -->
+        <!--  <item>sauna</item> -->
+        <item>telephone</item>
+        <item>toilets</item>
+        <!-- Building -->
+        <item>hotel</item>
+        <item>church</item>
+        <!-- <item>train_station</item> => station prefered -->
+        <!-- Craft -->
+        <!-- Emergency -->
+        <!-- <item>ambulance_station</item> -->
+        <!-- <item>phone</item> -->
+        <!-- Highway -->
+        <!-- <item>speed_camera</item> -->
+        <!-- Historic -->
+        <item>castle</item>
+        <item>monument</item>
+        <!-- Land use -->
+        <item>cemetery</item>
+        <!-- Leisure -->
+        <!-- <item>dance</item> -->
+        <!-- <item>golf_course</item> -->
+        <item>park</item>
+        <item>stadium</item>
+        <!-- <item>swimming_pool</item> -->
+        <!-- Natural -->
+        <item>beach</item>
+        <!-- Public Transport -->
+        <item>station</item>
+        <!-- Shop -->
+        <item>bakery</item>
+        <item>butcher</item>
+        <!-- <item>car_repair</item> -->
+        <!-- <item>clothes</item> -->
+        <!-- <item>convenience</item> -->
+        <item>florist</item>
+        <item>hairdresser</item>
+        <!-- <item>jewelry</item> -->
+        <item>kiosk</item>
+        <item>laundry</item>
+        <item>mall</item>
+        <item>optician</item>
+        <!-- <item>shoes</item> -->
+        <item>supermarket</item>
+        <!-- Sport -->
+        <!-- <item>golf</item> -->
+        <!-- <item>horse_racing</item> -->
+        <!-- <item>judo</item> -->
+        <!-- <item>karting</item> -->
+        <!-- <item>tennis</item> -->
+        <!-- Tourism -->
+        <item>information</item>
+        <item>museum</item>
+        <item>viewpoint</item>
+        <item>zoo</item>
+        <!-- Non-Nominatim tags, for other services: -->
+        <item>wikipedia</item>
+        <item>flickr</item>
+        <item>picasa</item>
+        <item>foursquare</item>
+    </string-array>
+</resources>
diff --git a/vtm-app/res/values/route.xml b/vtm-app/res/values/route.xml
new file mode 100644
index 00000000..acc78aab
--- /dev/null
+++ b/vtm-app/res/values/route.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="route_lookup_error">Route search failed</string>
+</resources>
diff --git a/vtm-app/res/values/settings.xml b/vtm-app/res/values/settings.xml
new file mode 100644
index 00000000..de4977ba
--- /dev/null
+++ b/vtm-app/res/values/settings.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+
+    <string-array name="preferences_map_database_keys">
+        <item>OPENSCIENCEMAP1</item>
+        <item>OPENSCIENCEMAP2</item>
+        <item>OPENSCIENCEMAP4</item>
+        <item>MAPNIK_VECTOR</item>
+        <item>MAPSFORGE</item>
+        <!-- <item>POSTGIS_READER</item> -->
+    </string-array>
+    <string-array name="preferences_map_generator_values">
+        <item>OpenScienceMap1</item>
+        <item>OpenScienceMap2</item>
+        <item>OpenScienceMap4</item>
+        <item>Mapnik-Vector</item>
+        <item>Mapsforge File</item>
+        <!-- <item>PostGIS</item> -->
+    </string-array>
+
+    <string name="preferences_map_database_default">OSCIMAP_READER</string>
+
+    <string-array name="preferences_map_theme_keys">
+        <item>DEFAULT</item>
+        <item>TRONRENDER</item>
+        <item>OSMARENDER</item>
+        <!--  <item>MAPNIK</item> -->
+    </string-array>
+    <string-array name="preferences_map_theme_values">
+        <item>Default</item>
+        <item>Tubes</item>
+        <item>Osmarender</item>
+        <!-- <item>Mapnik</item> -->
+    </string-array>
+
+    <string name="preferences_map_theme_default">OSMARENDER</string>
+    <string name="preferences_debug">Debug settings</string>
+    <string name="preferences_theme_title">Theme settings</string>
+    <string name="preferences_theme">Theme</string>
+    <string name="preferences_theme_summary">Change the theme of the map</string>
+    <string name="preferences_about">About</string>
+    <string name="preferences_about_summary">Show us!</string>
+    <string name="preferences_general">General settings</string>
+    <string name="preferences_cache_persistence">Cache persistence</string>
+    <string name="preferences_cache_persistence_desc">Keep cached images on exit</string>
+    <string name="preferences_cache_size">External storage</string>
+    <string name="preferences_cache_size_desc">Adjust the size of the cache</string>
+    <string name="preferences_cache_size_value">%.1f MB</string>
+    <string name="preferences_fullscreen">Full screen mode</string>
+    <string name="preferences_fullscreen_desc">Hide the status bar</string>
+    <string name="preferences_fix_orientation">Fix screen orientation</string>
+    <string name="preferences_fix_orientation_desc">Fix screen orientation</string>
+    <string name="preferences_map">Map settings</string>
+    <string name="preferences_map_view_mode">Map source</string>
+    <string name="preferences_map_view_mode_desc">Select map data source</string>
+    <string name="preferences_move_speed">Move speed</string>
+    <string name="preferences_move_speed_desc">Adjust the move speed of the map</string>
+    <string name="preferences_move_speed_value">%d %% move speed</string>
+    <string name="preferences_scale_bar_unit">Scale bar unit</string>
+    <string name="preferences_scale_bar_unit_desc">Select the unit for the map scale bar</string>
+    <string name="preferences_show_fps_counter">Frame rate</string>
+    <string name="preferences_show_fps_counter_desc">Enable frames per second counter</string>
+    <string name="preferences_show_scale_bar">Map scale bar</string>
+    <string name="preferences_show_scale_bar_desc">Show the scale of the map</string>
+    <string name="preferences_show_tile_coordinates">Tile coordinates</string>
+    <string name="preferences_show_tile_coordinates_desc">Show coordinates on tiles</string>
+    <string name="preferences_show_unmatched_ways">Draw unmatched ways</string>
+    <string name="preferences_show_tile_frames">Tile boundaries</string>
+    <string name="preferences_show_tile_frames_desc">Draw tile boundaries</string>
+    <string name="preferences_disable_polygons">Disable Polygon rendering</string>
+    <string name="preferences_debug_labels">Debug Labels</string>
+    <string name="preferences_show_water_tiles_desc">Highlight tiles which have the water flag set</string>
+    <string name="preferences_text_scale">Font size</string>
+    <string name="preferences_text_scale_desc">Select the text size of map labels</string>
+    <string name="preferences_wake_lock">Stay awake</string>
+    <string name="preferences_wake_lock_desc">Stop the screen from dimming</string>
+
+    <!--
+     <string-array name="view_sections">
+        <item>Map</item>
+        <item>Routes</item>
+        <item>Overlays</item>
+        <item>etc</item>
+    </string-array>
+
+    <string-array name="preferences_scale_bar_unit_keys">
+        <item>imperial</item>
+        <item>metric</item>
+    </string-array>
+    <string-array name="preferences_scale_bar_unit_values">
+        <item>Imperial</item>
+        <item>Metric</item>
+    </string-array>
+
+    <string name="preferences_scale_bar_unit_default">metric</string>
+
+    <string-array name="preferences_text_scale_keys">
+        <item>0.7</item>
+        <item>0.85</item>
+        <item>1.0</item>
+        <item>1.3</item>
+        <item>1.6</item>
+    </string-array>
+    <string-array name="preferences_text_scale_values">
+        <item>tiny</item>
+        <item>small</item>
+        <item>normal</item>
+        <item>large</item>
+        <item>huge</item>
+    </string-array>
+
+    <string name="preferences_text_scale_default">1.0</string>
+    -->
+
+</resources>
\ No newline at end of file
diff --git a/vtm-app/res/values/strings.xml b/vtm-app/res/values/strings.xml
new file mode 100755
index 00000000..3005c92d
--- /dev/null
+++ b/vtm-app/res/values/strings.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+
+    <string name="application_name">OpenScienceMap</string>
+    <string name="ok">OK</string>
+    <string name="cancel">Cancel</string>
+    <string name="error">Error</string>
+    <string name="error_last_location_unknown">The last location is unknown</string>
+    <string name="file_invalid">The selected file is invalid.</string>
+    <string name="file_select">Please select a file.</string>
+    <string name="file_size_byte">byte</string>
+    <string name="file_size_bytes">bytes</string>
+    <string name="file_size_kb">kB</string>
+    <string name="file_size_mb">MB</string>
+    <string name="file_size_gb">GB</string>
+    <string name="go_to_position">Go to position</string>
+    <string name="info_map_file_area">Area</string>
+    <string name="info_map_file_comment">Comment</string>
+    <string name="info_map_file_created_by">Created by</string>
+    <string name="info_map_file_date">Date</string>
+    <string name="info_map_file_debug">Debug information</string>
+    <string name="info_map_file_debug_no">not included</string>
+    <string name="info_map_file_debug_yes">included</string>
+    <string name="info_map_file_language_preference">Language preference</string>
+    <string name="info_map_file_name">File</string>
+    <string name="info_map_file_size">File size</string>
+    <string name="info_map_file_start_position">Start position</string>
+    <string name="info_map_file_start_zoom_level">Start zoom level</string>
+    <string name="info_map_file_version">Version</string>
+    <string name="latitude">Latitude</string>
+    <string name="longitude">Longitude</string>
+    <string name="menu_info">Info</string>
+    <string name="menu_settings">Settings</string>
+    <string name="menu_layers">Layers</string>
+    <string name="menu_layer_grid">Grid</string>
+    <string name="menu_layer_naturalearth">Natural Earth</string>
+    <string name="menu_layer_openstreetmap">OpenStreetMap</string>
+    <string name="menu_info_map_file">Map file properties</string>
+    <string name="menu_find">Find</string>
+    <string name="menu_info_about">About</string>
+    <string name="menu_mapfile">Map file</string>
+    <string name="menu_position">Position</string>
+    <string name="menu_compass_enable">Compass</string>
+    <string name="menu_position_enter_coordinates">Enter coordinates</string>
+    <string name="menu_position_last_known">Last known location</string>
+    <string name="menu_position_map_file_center">Map file center</string>
+    <string name="menu_position_my_location_enable">Show my location</string>
+    <string name="menu_position_follow_location">Follow my location</string>
+    <string name="menu_compass">Compass</string>
+    <string name="menu_compass_2d">Compass 2D</string>
+    <string name="menu_compass_3d">Compass 3D</string>
+    <string name="menu_compass_off">Compass Off</string>
+    <string name="menu_preferences">Preferences</string>
+    <string name="menu_render_theme">Theme</string>
+    <string name="no_location_provider_available">No location source available</string>
+    <string name="snap_to_location_enabled">Snap to position is activated</string>
+    <string name="snap_to_location_disabled">Snap to position is disabled</string>
+    <string name="unit_symbol_kilometer">&#160;km</string>
+    <string name="unit_symbol_meter">&#160;m</string>
+    <string name="zoomLevel">Zoom level</string>
+    <string name="menu_options">Options</string>
+    <string name="menu_pois">Bars nearby</string>
+    <string name="menu_poi_list">List POIs</string>
+    <string name="departure">Departure</string>
+    <string name="destination">Destination</string>
+    <string name="viapoint">Via-Point</string>
+
+</resources>
\ No newline at end of file
diff --git a/vtm-app/res/values/styles.xml b/vtm-app/res/values/styles.xml
new file mode 100644
index 00000000..4dba0d0a
--- /dev/null
+++ b/vtm-app/res/values/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
\ No newline at end of file
diff --git a/vtm-app/res/xml/preferences.xml b/vtm-app/res/xml/preferences.xml
new file mode 100644
index 00000000..a00d48a4
--- /dev/null
+++ b/vtm-app/res/xml/preferences.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:oscim_app="http://app.oscim.org"
+    android:title="@string/menu_preferences">
+
+    <!--    <PreferenceCategory android:title="@string/preferences_map" > -->
+    <!--
+               <CheckBoxPreference
+              android:key="showScaleBar"
+              android:summary="@string/preferences_show_scale_bar_desc"
+              android:title="@string/preferences_show_scale_bar" />
+               <ListPreference
+              android:defaultValue="@string/preferences_scale_bar_unit_default"
+              android:dependency="showScaleBar"
+              android:entries="@array/preferences_scale_bar_unit_values"
+              android:entryValues="@array/preferences_scale_bar_unit_keys"
+              android:key="scaleBarUnit"
+              android:summary="@string/preferences_scale_bar_unit_desc"
+              android:title="@string/preferences_scale_bar_unit" />
+    -->
+
+
+    <ListPreference
+        android:defaultValue="@string/preferences_map_database_default"
+        android:entries="@array/preferences_map_generator_values"
+        android:entryValues="@array/preferences_map_database_keys"
+        android:key="mapDatabase"
+        android:summary="@string/preferences_map_view_mode_desc"
+        android:title="@string/preferences_map_view_mode" />
+
+
+    <!--
+               <ListPreference
+              android:defaultValue="@string/preferences_text_scale_default"
+              android:entries="@array/preferences_text_scale_values"
+              android:entryValues="@array/preferences_text_scale_keys"
+              android:key="textScale"
+              android:summary="@string/preferences_text_scale_desc"
+              android:title="@string/preferences_text_scale" />
+    -->
+    <!--  </PreferenceCategory> -->
+
+    <PreferenceCategory android:title="@string/preferences_theme_title">
+        <ListPreference
+            android:defaultValue="@string/preferences_map_theme_default"
+            android:entries="@array/preferences_map_theme_values"
+            android:entryValues="@array/preferences_map_theme_keys"
+            android:key="theme"
+            android:summary="@string/preferences_theme_summary"
+            android:title="@string/preferences_theme" />
+    </PreferenceCategory>
+
+    <PreferenceCategory android:title="User Interface">
+        <CheckBoxPreference
+            android:title="Distance Touch"
+            android:summary="Show Route between two Points"
+            android:key="distanceTouch" />
+    </PreferenceCategory>
+
+    <PreferenceCategory android:title="Cache">
+        <org.oscim.app.preferences.CacheSizePreference
+            android:defaultValue="30"
+            android:key="cacheSize"
+            android:max="50"
+            android:summary="Set tile cache size"
+            android:title="Cache Size"
+            oscim_app:min="1"
+            oscim_app:unitsLeft=""
+            oscim_app:unitsRight="MB" />
+
+        <!-- http://stackoverflow.com/questions/5298370/how-to-add-a-button-to-a-preferencescreen-android?rq=1 -->
+        <Preference
+            android:key="clear_cache"
+            android:summary="Delete all cached tiles"
+            android:title="Clear Cache" />
+    </PreferenceCategory>
+
+    <!--
+      <PreferenceCategory android:title="@string/preferences_general" >
+          <CheckBoxPreference
+              android:key="fullscreen"
+              android:summary="@string/preferences_fullscreen_desc"
+              android:title="@string/preferences_fullscreen" />
+          <CheckBoxPreference
+              android:key="fixOrientation"
+              android:summary="@string/preferences_fix_orientation"
+              android:title="@string/preferences_fix_orientation_desc" />
+          <CheckBoxPreference
+              android:key="wakeLock"
+              android:summary="@string/preferences_wake_lock_desc"
+              android:title="@string/preferences_wake_lock" />
+        <CheckBoxPreference android:title="@string/preferences_cache_persistence" android:summary="@string/preferences_cache_persistence_desc"
+              android:key="cachePersistence" />
+          <de.sfb.pampa.preferences.CacheSizePreference
+              android:title="@string/preferences_cache_size" android:summary="@string/preferences_cache_size_desc" android:key="cacheSize" />
+          <de.sfb.pampa.preferences.MoveSpeedPreference
+              android:title="@string/preferences_move_speed" android:summary="@string/preferences_move_speed_desc" android:key="moveSpeed" />
+      </PreferenceCategory>
+    -->
+
+
+    <!--
+      <PreferenceCategory android:title="@string/preferences_debug" >
+
+             <CheckBoxPreference android:title="@string/preferences_show_fps_counter" android:summary="@string/preferences_show_fps_counter_desc"
+              android:key="showFpsCounter" />
+          <CheckBoxPreference
+              android:key="drawTileFrames"
+              android:summary="@string/preferences_show_tile_frames_desc"
+              android:title="@string/preferences_show_tile_frames" />
+          <CheckBoxPreference
+              android:key="drawUnmatchedWays"
+              android:summary="@string/preferences_show_unmatched_ways"
+              android:title="@string/preferences_show_unmatched_ways" />
+          <CheckBoxPreference
+              android:key="disablePolygons"
+              android:summary="@string/preferences_disable_polygons"
+              android:title="@string/preferences_disable_polygons" />
+          <CheckBoxPreference
+              android:key="debugLabels"
+              android:summary="@string/preferences_debug_labels"
+              android:title="@string/preferences_debug_labels" />
+      </PreferenceCategory>
+    -->
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/vtm-app/src/android-logger.properties b/vtm-app/src/android-logger.properties
new file mode 100644
index 00000000..47f60ed5
--- /dev/null
+++ b/vtm-app/src/android-logger.properties
@@ -0,0 +1 @@
+root=DEBUG:%logger
\ No newline at end of file
diff --git a/vtm-app/src/org/oscim/app/App.java b/vtm-app/src/org/oscim/app/App.java
new file mode 100644
index 00000000..7f95c9a5
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/App.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.view.Display;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import org.oscim.android.MapView;
+import org.oscim.map.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class App extends Application {
+
+    public final static Logger log = LoggerFactory.getLogger(App.class);
+
+    public static Map map;
+    public static MapView view;
+    public static Resources res;
+    public static TileMap activity;
+
+    public static POISearch poiSearch;
+    public static RouteSearch routeSearch;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        res = getResources();
+    }
+
+    public static void lockOrientation(Activity activity) {
+        Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
+        int rotation = display.getRotation();
+        int tempOrientation = activity.getResources().getConfiguration().orientation;
+        int orientation = 0;
+        switch (tempOrientation) {
+            case Configuration.ORIENTATION_LANDSCAPE:
+                if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90)
+                    orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+                else
+                    orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+                break;
+            case Configuration.ORIENTATION_PORTRAIT:
+                if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270)
+                    orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+                else
+                    orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+        }
+        activity.setRequestedOrientation(orientation);
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/ConnectionHandler.java b/vtm-app/src/org/oscim/app/ConnectionHandler.java
new file mode 100644
index 00000000..5be003ee
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/ConnectionHandler.java
@@ -0,0 +1,31 @@
+package org.oscim.app;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.widget.Toast;
+
+public class ConnectionHandler extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        ConnectivityManager connectivityManager = (ConnectivityManager) context
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
+        //        NetworkInfo mobNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE );
+        if (activeNetInfo != null) {
+            if (activeNetInfo.isConnected()) {
+                Toast.makeText(context, "Active Network Type : " + activeNetInfo.getTypeName(),
+                        Toast.LENGTH_SHORT).show();
+                //if (App.map != null)
+                //    App.map.redrawMap();
+            }
+            //Toast.makeText( context, "Active Network Type : " + activeNetInfo.getTypeName(), Toast.LENGTH_SHORT ).show();
+        }
+        //        if( mobNetInfo != null )
+        //        {
+        //          Toast.makeText( context, "Mobile Network Type : " + mobNetInfo.getTypeName(), Toast.LENGTH_SHORT ).show();
+        //        }
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/FileUtils.java b/vtm-app/src/org/oscim/app/FileUtils.java
new file mode 100644
index 00000000..f541cab5
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/FileUtils.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app;
+
+import android.content.res.Resources;
+
+import java.text.DecimalFormat;
+
+final class FileUtils {
+    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.00 ");
+    private static final double ONE_GIGABYTE = 1000000000;
+    private static final double ONE_KILOBYTE = 1000;
+    private static final double ONE_MEGABYTE = 1000000;
+
+    /**
+     * Formats the given file size as a human readable string, using SI
+     * prefixes.
+     *
+     * @param fileSize  the file size to be formatted.
+     * @param resources a reference to the application resources.
+     * @return a human readable file size.
+     * @throws IllegalArgumentException if the given file size is negative.
+     */
+    static String formatFileSize(long fileSize, Resources resources) {
+        if (fileSize < 0) {
+            throw new IllegalArgumentException("invalid file size: " + fileSize);
+        } else if (fileSize < 1000) {
+            if (fileSize == 1) {
+                // singular
+                return "1 " + resources.getString(R.string.file_size_byte);
+            }
+
+            // plural, including zero
+            return fileSize + " " + resources.getString(R.string.file_size_bytes);
+        } else {
+            if (fileSize < ONE_MEGABYTE) {
+                return DECIMAL_FORMAT.format(fileSize / ONE_KILOBYTE)
+                        + resources.getString(R.string.file_size_kb);
+            } else if (fileSize < ONE_GIGABYTE) {
+                return DECIMAL_FORMAT.format(fileSize / ONE_MEGABYTE)
+                        + resources.getString(R.string.file_size_mb);
+            }
+            return DECIMAL_FORMAT.format(fileSize / ONE_GIGABYTE)
+                    + resources.getString(R.string.file_size_gb);
+        }
+    }
+
+    private FileUtils() {
+        throw new IllegalStateException();
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/InfoView.java b/vtm-app/src/org/oscim/app/InfoView.java
new file mode 100644
index 00000000..fccb65fd
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/InfoView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.WindowManager;
+import android.webkit.WebView;
+
+/**
+ * Simple activity to display the info web page from the assets folder.
+ */
+public class InfoView extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        WebView webView = new WebView(this);
+        webView.loadUrl("file:///android_asset/info.xml");
+        setContentView(webView);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        // check if the full screen mode should be activated
+        if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen", false)) {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        } else {
+            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        }
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/MapActivity.java b/vtm-app/src/org/oscim/app/MapActivity.java
new file mode 100644
index 00000000..4ac879b2
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/MapActivity.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2013 Hannes Janetzek
+ *
+ * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+
+import org.oscim.android.MapView;
+import org.oscim.core.GeoPoint;
+import org.oscim.core.MapPosition;
+import org.oscim.map.Map;
+
+/**
+ * MapActivity is the abstract base class which can be extended in order to use
+ * a {@link MapView}. There are no abstract methods in this implementation which
+ * subclasses need to override and no API key or registration is required.
+ * <p/>
+ * A subclass may create a MapView either via one of the MapView constructors or
+ * by inflating an XML layout file.
+ * <p/>
+ * When the MapActivity is shut down, the current center position, zoom level
+ * and map file of the MapView are saved in a preferences file and restored in
+ * the next startup process.
+ */
+public abstract class MapActivity extends Activity {
+    private static final String KEY_LATITUDE = "latitude";
+    private static final String KEY_LONGITUDE = "longitude";
+    private static final String KEY_MAP_SCALE = "map_scale";
+
+    private static final String PREFERENCES_FILE = "MapActivity";
+
+    private static boolean containsViewport(SharedPreferences sharedPreferences) {
+        return sharedPreferences.contains(KEY_LATITUDE)
+                && sharedPreferences.contains(KEY_LONGITUDE)
+                && sharedPreferences.contains(KEY_MAP_SCALE);
+    }
+
+    protected Map mMap;
+    protected MapView mMapView;
+
+    public Map map() {
+        return mMap;
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mMap.destroy();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        Editor editor = getSharedPreferences(PREFERENCES_FILE, MODE_PRIVATE).edit();
+        editor.clear();
+
+        // save the map position
+        MapPosition mapPosition = new MapPosition();
+
+        mMap.viewport().getMapPosition(mapPosition);
+
+        GeoPoint geoPoint = mapPosition.getGeoPoint();
+
+        editor.putInt(KEY_LATITUDE, geoPoint.latitudeE6);
+        editor.putInt(KEY_LONGITUDE, geoPoint.longitudeE6);
+        editor.putFloat(KEY_MAP_SCALE, (float) mapPosition.scale);
+
+        editor.commit();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mMapView.onResume();
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mMapView.onPause();
+    }
+
+    /**
+     * This method is called once by each MapView during its setup process.
+     *
+     * @param mapView the calling MapView.
+     */
+    public final void registerMapView(MapView mapView) {
+        mMapView = mapView;
+        mMap = mapView.map();
+
+        SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCES_FILE,
+                MODE_PRIVATE);
+
+        if (containsViewport(sharedPreferences)) {
+            // get and set the map position and zoom level
+            int latitudeE6 = sharedPreferences.getInt(KEY_LATITUDE, 0);
+            int longitudeE6 = sharedPreferences.getInt(KEY_LONGITUDE, 0);
+            float scale = sharedPreferences.getFloat(KEY_MAP_SCALE, 1);
+
+            MapPosition mapPosition = new MapPosition();
+            mapPosition.setPosition(latitudeE6 / 1E6, longitudeE6 / 1E6);
+            mapPosition.setScale(scale);
+
+            mMap.setMapPosition(mapPosition);
+        }
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/MapLayers.java b/vtm-app/src/org/oscim/app/MapLayers.java
new file mode 100644
index 00000000..0af4fd8f
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/MapLayers.java
@@ -0,0 +1,189 @@
+package org.oscim.app;
+
+import android.content.SharedPreferences;
+
+import org.oscim.android.cache.TileCache;
+import org.oscim.layers.GenericLayer;
+import org.oscim.layers.Layer;
+import org.oscim.layers.TileGridLayer;
+import org.oscim.layers.tile.bitmap.BitmapTileLayer;
+import org.oscim.layers.tile.buildings.BuildingLayer;
+import org.oscim.layers.tile.vector.VectorTileLayer;
+import org.oscim.layers.tile.vector.labeling.LabelLayer;
+import org.oscim.theme.ThemeFile;
+import org.oscim.theme.VtmThemes;
+import org.oscim.tiling.ITileCache;
+import org.oscim.tiling.TileSource;
+import org.oscim.tiling.source.UrlTileSource;
+import org.oscim.tiling.source.bitmap.DefaultSources;
+import org.oscim.tiling.source.mapfile.MapFileTileSource;
+import org.oscim.tiling.source.mapnik.MapnikVectorTileSource;
+import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MapLayers {
+
+    final static Logger log = LoggerFactory.getLogger(MapLayers.class);
+
+    private static final String CACHE_DIRECTORY = "/Android/data/org.oscim.app/cache/";
+
+    abstract static class Config {
+        final String name;
+
+        public Config(String name) {
+            this.name = name;
+        }
+
+        abstract TileSource init();
+    }
+
+    static Config[] configs = new Config[]{new Config("OPENSCIENCEMAP4") {
+        TileSource init() {
+            return new OSciMap4TileSource();
+        }
+    }, new Config("MAPSFORGE") {
+        TileSource init() {
+            return new MapFileTileSource().setOption("file",
+                    "/storage/sdcard0/germany.map");
+        }
+    }, new Config("MAPNIK_VECTOR") {
+        TileSource init() {
+            return new MapnikVectorTileSource();
+        }
+    }};
+
+    private VectorTileLayer mBaseLayer;
+    private String mMapDatabase;
+    private ITileCache mCache;
+
+    private GenericLayer mGridOverlay;
+    private boolean mGridEnabled;
+
+    // FIXME -> implement LayerGroup
+    private int mBackgroundId = -2;
+    private Layer mBackroundPlaceholder;
+    private Layer mBackgroundLayer;
+
+    public MapLayers() {
+        mBackroundPlaceholder = new Layer(null) {
+        };
+        setBackgroundMap(-1);
+    }
+
+    void setBaseMap(SharedPreferences preferences) {
+        String dbname = preferences.getString("mapDatabase", "OPENSCIENCEMAP4");
+
+        if (dbname.equals(mMapDatabase) && mBaseLayer != null)
+            return;
+
+        TileSource tileSource = null;
+        for (Config c : configs)
+            if (c.name.equals(dbname))
+                tileSource = c.init();
+
+        if (tileSource == null) {
+            tileSource = configs[0].init();
+            dbname = configs[0].name;
+            preferences.edit().putString("mapDatabase", dbname).commit();
+        }
+
+        if (tileSource instanceof UrlTileSource) {
+            mCache = new TileCache(App.activity, CACHE_DIRECTORY, dbname);
+            mCache.setCacheSize(512 * (1 << 10));
+            tileSource.setCache(mCache);
+        } else {
+            mCache = null;
+        }
+
+        if (mBaseLayer == null) {
+            mBaseLayer = App.map.setBaseMap(tileSource);
+            App.map.layers().add(2, new BuildingLayer(App.map, mBaseLayer));
+            App.map.layers().add(3, new LabelLayer(App.map, mBaseLayer));
+        } else
+            mBaseLayer.setTileSource(tileSource);
+
+        mMapDatabase = dbname;
+    }
+
+    void setPreferences(SharedPreferences preferences) {
+        setBaseMap(preferences);
+
+        ThemeFile theme = VtmThemes.DEFAULT;
+        if (preferences.contains("theme")) {
+            String name = preferences.getString("theme", "DEFAULT");
+            try {
+                theme = VtmThemes.valueOf(name);
+            } catch (IllegalArgumentException e) {
+                theme = VtmThemes.DEFAULT;
+            }
+        }
+
+        App.map.setTheme(theme);
+
+        // default cache size 20MB
+        int cacheSize = preferences.getInt("cacheSize", 20);
+
+        if (mCache != null)
+            mCache.setCacheSize(cacheSize * (1 << 20));
+
+    }
+
+    void enableGridOverlay(boolean enable) {
+        if (mGridEnabled == enable)
+            return;
+
+        if (enable) {
+            if (mGridOverlay == null)
+                mGridOverlay = new TileGridLayer(App.map);
+
+            App.map.layers().add(mGridOverlay);
+        } else {
+            App.map.layers().remove(mGridOverlay);
+        }
+
+        mGridEnabled = enable;
+        App.map.updateMap(true);
+    }
+
+    boolean isGridEnabled() {
+        return mGridEnabled;
+    }
+
+    void setBackgroundMap(int id) {
+        if (id == mBackgroundId)
+            return;
+
+        App.map.layers().remove(mBackgroundLayer);
+        mBackgroundLayer = null;
+
+        switch (id) {
+            case R.id.menu_layer_openstreetmap:
+                mBackgroundLayer = new BitmapTileLayer(App.map, DefaultSources.OPENSTREETMAP.build());
+                break;
+
+            case R.id.menu_layer_naturalearth:
+                mBackgroundLayer = new BitmapTileLayer(App.map, DefaultSources.NE_LANDCOVER.build());
+                break;
+            default:
+                mBackgroundLayer = mBackroundPlaceholder;
+                id = -1;
+        }
+
+        if (mBackgroundLayer instanceof BitmapTileLayer)
+            App.map.setBaseMap((BitmapTileLayer) mBackgroundLayer);
+        else
+            App.map.layers().add(1, mBackroundPlaceholder);
+
+        mBackgroundId = id;
+    }
+
+    int getBackgroundId() {
+        return mBackgroundId;
+    }
+
+    public void deleteCache() {
+        if (mCache != null)
+            mCache.setCacheSize(0);
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/POIActivity.java b/vtm-app/src/org/oscim/app/POIActivity.java
new file mode 100644
index 00000000..930f3f15
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/POIActivity.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2012 osmdroidbonuspack: M.Kergall
+ * Copyright 2012 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.oscim.app;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import org.osmdroid.location.FourSquareProvider;
+import org.osmdroid.location.POI;
+
+import java.util.List;
+
+/**
+ * Activity showing POIs as a list.
+ *
+ * @author M.Kergall
+ */
+
+// TODO implement:
+// http://codehenge.net/blog/2011/06/android-development-tutorial-
+//        asynchronous-lazy-loading-and-caching-of-listview-images/
+
+public class POIActivity extends Activity {
+
+    AutoCompleteTextView poiTagText;
+    POIAdapter mAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.items_list);
+
+        ListView list = (ListView) findViewById(R.id.items);
+
+        Intent myIntent = getIntent();
+
+        final List<POI> pois = App.poiSearch.getPOIs();
+        final int currentNodeId = myIntent.getIntExtra("ID", -1);
+        POIAdapter adapter = new POIAdapter(this, pois);
+        mAdapter = adapter;
+
+        list.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> arg0, View view, int position, long index) {
+                //log.debug("poi on click: " + position);
+                Intent intent = new Intent();
+                intent.putExtra("ID", position);
+                setResult(RESULT_OK, intent);
+                finish();
+            }
+        });
+
+        list.setAdapter(adapter);
+        list.setSelection(currentNodeId);
+
+        // POI search interface:
+        String[] poiTags = getResources().getStringArray(R.array.poi_tags);
+        poiTagText = (AutoCompleteTextView) findViewById(R.id.poiTag);
+        ArrayAdapter<String> textadapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_dropdown_item_1line,
+                poiTags);
+        poiTagText.setAdapter(textadapter);
+
+        //        Button setPOITagButton = (Button) findViewById(R.id.buttonSetPOITag);
+        //        setPOITagButton.setOnClickListener(new View.OnClickListener() {
+        //            @Override
+        //            public void onClick(View v) {
+        //                hideKeyboard();
+        //                //Start search:
+        //                App.poiSearch.getPOIAsync(poiTagText.getText().toString());
+        //            }
+        //        });
+
+        // FIXME!
+        Button btn = (Button) findViewById(R.id.pois_btn_flickr);
+        btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                hideKeyboard();
+                App.poiSearch.getPOIAsync(POISearch.TAG_FLICKR);
+            }
+        });
+
+        btn = (Button) findViewById(R.id.pois_btn_nominatim);
+        btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                hideKeyboard();
+                String text = poiTagText.getText().toString();
+                if (text == null || text.length() == 0)
+                    App.poiSearch.getPOIAsync("bremen");
+                else
+                    App.poiSearch.getPOIAsync(text);
+            }
+        });
+
+        btn = (Button) findViewById(R.id.pois_btn_wikipedia);
+        btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                hideKeyboard();
+                App.poiSearch.getPOIAsync(POISearch.TAG_WIKIPEDIA);
+            }
+        });
+
+        btn = (Button) findViewById(R.id.pois_btn_foursquare);
+        btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                hideKeyboard();
+                App.poiSearch.getPOIAsync(POISearch.TAG_FOURSQUARE
+                        + poiTagText.getText().toString());
+            }
+        });
+
+        registerForContextMenu(list);
+
+        // only show keyboard when nothing in the list yet
+        if (pois == null || pois.size() == 0) {
+            poiTagText.postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    InputMethodManager keyboard = (InputMethodManager)
+                            getSystemService(Context.INPUT_METHOD_SERVICE);
+                    keyboard.showSoftInput(poiTagText, 0);
+                }
+            }, 200);
+        }
+    }
+
+    private void hideKeyboard() {
+        InputMethodManager imm = (InputMethodManager)
+                getSystemService(Context.INPUT_METHOD_SERVICE);
+        imm.hideSoftInputFromWindow(poiTagText.getWindowToken(), 0);
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        // from SearchableDictionary Example:
+        // Because this activity has set launchMode="singleTop", the system calls this method
+        // to deliver the intent if this activity is currently the foreground activity when
+        // invoked again (when the user executes a search from this activity, we don't create
+        // a new instance of this activity, so the system delivers the search intent here)
+        //            handleIntent(intent);
+
+        //        final ArrayList<POI> pois = intent.getParcelableArrayListExtra("POI");
+        //        final int currentNodeId = intent.getIntExtra("ID", -1);
+        //        POIAdapter adapter = new POIAdapter(this, pois);
+        //        mAdapter.setPOI(pois);
+        mAdapter.notifyDataSetChanged();
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+                                    ContextMenuInfo menuInfo) {
+        if (v.getId() == R.id.items) {
+            //AdapterView.AdapterContextMenuInfo info =
+            // (AdapterView.AdapterContextMenuInfo) menuInfo;
+            //log.debug("list context menu created " + info.position);
+
+            MenuInflater inflater = getMenuInflater();
+            inflater.inflate(R.menu.poi_menu, menu);
+
+        }
+
+        super.onCreateContextMenu(menu, v, menuInfo);
+
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        //log.debug("context menu item selected " + item.getItemId());
+
+        if (item.getItemId() == R.id.menu_link) {
+
+            AdapterView.AdapterContextMenuInfo info =
+                    (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+
+            POI poi = (POI) mAdapter.getItem(info.position);
+            if (poi == null || poi.url == null)
+                return false;
+
+            if (poi.serviceId == POI.POI_SERVICE_4SQUARE) {
+                FourSquareProvider.browse(this, poi);
+                return true;
+            } else {
+                Intent i = new Intent(Intent.ACTION_VIEW);
+                i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+                i.setData(Uri.parse(poi.url));
+                startActivity(i);
+
+            }
+            return true;
+
+        }
+
+        return super.onContextItemSelected(item);
+    }
+
+    class POIObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            mAdapter.notifyDataSetChanged();
+        }
+    }
+}
+
+class POIAdapter extends BaseAdapter implements OnClickListener {
+    private Context mContext;
+    private final List<POI> mPois;
+
+    public POIAdapter(Context context, List<POI> pois) {
+        mContext = context;
+        mPois = pois;
+    }
+
+    @Override
+    public int getCount() {
+        if (mPois == null)
+            return 0;
+
+        return mPois.size();
+    }
+
+    @Override
+    public Object getItem(int position) {
+        if (mPois == null)
+            return null;
+
+        return mPois.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View view, ViewGroup viewGroup) {
+        POI entry = (POI) getItem(position);
+        if (view == null) {
+            LayoutInflater inflater = (LayoutInflater) mContext
+                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            view = inflater.inflate(R.layout.item_layout, null);
+
+            ViewHolder holder = new ViewHolder();
+            holder.title = (TextView) view.findViewById(R.id.title);
+            holder.details = (TextView) view.findViewById(R.id.details);
+            holder.thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
+            view.setTag(holder);
+        }
+
+        ViewHolder holder = (ViewHolder) view.getTag();
+
+        holder.title.setText((entry.url == null ? "" : "[link] ") + entry.type);
+        holder.details.setText(entry.description);
+
+        entry.fetchThumbnail(holder.thumbnail);
+
+        return view;
+    }
+
+    @Override
+    public void onClick(View arg0) {
+        //nothing to do.
+    }
+
+    class ViewHolder {
+        public TextView title;
+        public TextView details;
+        public ImageView thumbnail;
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/POISearch.java b/vtm-app/src/org/oscim/app/POISearch.java
new file mode 100644
index 00000000..b79c4750
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/POISearch.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2012 osmdroid: M.Kergall
+ * Copyright 2012 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import org.oscim.android.canvas.AndroidGraphics;
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.oscim.layers.marker.MarkerItem.HotspotPlace;
+import org.oscim.layers.marker.MarkerSymbol;
+import org.oscim.map.Map;
+import org.osmdroid.location.FlickrPOIProvider;
+import org.osmdroid.location.FourSquareProvider;
+import org.osmdroid.location.GeoNamesPOIProvider;
+import org.osmdroid.location.NominatimPOIProvider;
+import org.osmdroid.location.POI;
+import org.osmdroid.location.PicasaPOIProvider;
+import org.osmdroid.overlays.DefaultInfoWindow;
+import org.osmdroid.overlays.ExtendedMarkerItem;
+import org.osmdroid.overlays.ItemizedOverlayWithBubble;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class POISearch {
+    private final ArrayList<POI> mPOIs;
+    ItemizedOverlayWithBubble<ExtendedMarkerItem> poiMarkers;
+    MarkerSymbol[] mMarkers;
+
+    private final static int MDEFAULT = 0;
+    private final static int MFLICKR = 1;
+    private final static int MPICASA = 2;
+    private final static int MWIKI16 = 3;
+    private final static int MWIKI32 = 4;
+
+    POISearch() {
+        mPOIs = new ArrayList<POI>();
+        //POI markers:
+        final ArrayList<ExtendedMarkerItem> poiItems = new ArrayList<ExtendedMarkerItem>();
+
+        poiMarkers = new ItemizedOverlayWithBubble<ExtendedMarkerItem>(App.map,
+                App.activity,
+                null,
+                poiItems,
+                new POIInfoWindow(App.map));
+
+        App.map.layers().add(poiMarkers);
+
+        mMarkers = new MarkerSymbol[5];
+
+        mMarkers[MDEFAULT] = AndroidGraphics
+                .makeMarker(App.res.getDrawable(R.drawable.pin), HotspotPlace.BOTTOM_CENTER);
+
+        mMarkers[MFLICKR] = AndroidGraphics
+                .makeMarker(App.res.getDrawable(R.drawable.marker_poi_flickr), null);
+
+        mMarkers[MPICASA] = AndroidGraphics
+                .makeMarker(App.res.getDrawable(R.drawable.marker_poi_picasa_24), null);
+
+        mMarkers[MWIKI16] = AndroidGraphics
+                .makeMarker(App.res.getDrawable(R.drawable.marker_poi_wikipedia_16), null);
+
+        mMarkers[MWIKI32] = AndroidGraphics
+                .makeMarker(App.res.getDrawable(R.drawable.marker_poi_wikipedia_32), null);
+    }
+
+    public List<POI> getPOIs() {
+        return mPOIs;
+    }
+
+    final static String TAG_WIKIPEDIA = "wikipedia";
+    final static String TAG_FLICKR = "flickr";
+    final static String TAG_PICASA = "picasa";
+    final static String TAG_FOURSQUARE = "foursquare";
+
+    //private final static String TAG_NOMINATIM = "nominatim";
+
+    class POITask extends AsyncTask<Object, Void, List<POI>> {
+        String mTag;
+
+        @Override
+        protected List<POI> doInBackground(Object... params) {
+            mTag = (String) params[0];
+
+            if (mTag == null || mTag.equals("")) {
+                return null;
+            }
+            BoundingBox bb = App.map.getBoundingBox(0);
+
+            if (mTag.equals(TAG_WIKIPEDIA)) {
+                GeoNamesPOIProvider poiProvider = new GeoNamesPOIProvider("mkergall");
+                //ArrayList<POI> pois = poiProvider.getPOICloseTo(point, 30, 20.0);
+                //Get POI inside the bounding box of the current map view:
+
+                return poiProvider.getPOIInside(bb, 30);
+
+                //OverpassPOIProvider poiProvider = new OverpassPOIProvider();
+                //return poiProvider.getPOIInside(bb, "", 0);
+            } else if (mTag.equals(TAG_FLICKR)) {
+                FlickrPOIProvider poiProvider = new FlickrPOIProvider("c39be46304a6c6efda8bc066c185cd7e");
+                return poiProvider.getPOIInside(bb, null, 20);
+            } else if (mTag.startsWith(TAG_PICASA)) {
+                PicasaPOIProvider poiProvider = new PicasaPOIProvider(null);
+                String q = mTag.substring(7);
+                return poiProvider.getPOIInside(bb, q, 20);
+            } else if (mTag.startsWith(TAG_FOURSQUARE)) {
+                FourSquareProvider poiProvider = new FourSquareProvider(null, null);
+                String q = mTag.substring(10);
+                //                String q = mTag.substring("picasa".length());
+                return poiProvider.getPOIInside(bb, q, 40);
+            } else {
+                NominatimPOIProvider poiProvider = new NominatimPOIProvider();
+                //poiProvider.setService(NominatimPOIProvider.NOMINATIM_POI_SERVICE);
+
+                poiProvider.setService(NominatimPOIProvider.MAPQUEST_POI_SERVICE);
+
+                //pois = poiProvider.getPOIAlong(mRoute.getRouteLow(), mTag, 100, 2.0);
+                return poiProvider.getPOIInside(bb, mTag, 10);
+            }
+        }
+
+        @Override
+        protected void onPostExecute(List<POI> pois) {
+            if (mTag.equals("")) {
+                //no search, no message
+            } else if (pois == null) {
+                Toast.makeText(App.activity,
+                        "Technical issue when getting " + mTag + " POI.",
+                        Toast.LENGTH_SHORT).show();
+            } else {
+                Toast.makeText(App.activity,
+                        pois.size() + " " + mTag + " entries found",
+                        Toast.LENGTH_SHORT).show();
+
+                //    if (mTag.equals("flickr") || mTag.startsWith("picasa") || mTag.equals("wikipedia"))
+                //    startAsyncThumbnailsLoading(mPOIs);
+            }
+
+            updateUIWithPOI(pois);
+        }
+    }
+
+    void updateUIWithPOI(List<POI> pois) {
+        mPOIs.clear();
+        if (pois == null) {
+            showPOIActivity(true);
+            App.map.updateMap(true);
+            return;
+        }
+
+        mPOIs.addAll(pois);
+
+        for (POI poi : pois) {
+            String desc = null;
+            String name = null;
+
+            if (poi.serviceId == POI.POI_SERVICE_NOMINATIM) {
+                name = poi.description;
+                String[] split = name.split(", ");
+                if (split != null && split.length > 1) {
+                    name = split[0];
+                    desc = split[1];
+
+                    for (int i = 2; i < 3 && i < split.length; i++)
+                        desc += "," + split[i];
+                }
+
+            } else {
+                desc = poi.description;
+            }
+
+            ExtendedMarkerItem poiMarker =
+                    new ExtendedMarkerItem(poi.type + (name == null ? "" : ": " + name), desc,
+                            poi.location);
+            MarkerSymbol marker = null;
+
+            if (poi.serviceId == POI.POI_SERVICE_NOMINATIM) {
+
+                marker = mMarkers[MDEFAULT];
+            } else if (poi.serviceId == POI.POI_SERVICE_GEONAMES_WIKIPEDIA) {
+                if (poi.rank < 90)
+                    marker = mMarkers[MWIKI16];
+                else
+                    marker = mMarkers[MWIKI32];
+            } else if (poi.serviceId == POI.POI_SERVICE_FLICKR) {
+                marker = mMarkers[MFLICKR];
+            } else if (poi.serviceId == POI.POI_SERVICE_PICASA) {
+                marker = mMarkers[MPICASA];
+                poiMarker.setSubDescription(poi.category);
+            } else if (poi.serviceId == POI.POI_SERVICE_4SQUARE) {
+                marker = mMarkers[MDEFAULT];
+                poiMarker.setSubDescription(poi.category);
+            }
+
+            poiMarker.setMarker(marker);
+            //thumbnail loading moved in POIInfoWindow.onOpen for better performances.
+            poiMarker.setRelatedObject(poi);
+            poiMarkers.addItem(poiMarker);
+        }
+
+        showPOIActivity(true);
+        App.map.updateMap(true);
+    }
+
+    private void showPOIActivity(boolean setNew) {
+        // show or update
+        Intent intent = new Intent(App.activity, POIActivity.class);
+        intent.putExtra("ID", poiMarkers.getBubbledItemId());
+        if (setNew)
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+        App.activity.startActivityForResult(intent, TileMap.POIS_REQUEST);
+    }
+
+    void getPOIAsync(String tag) {
+        poiMarkers.removeAllItems();
+        new POITask().execute(tag);
+    }
+
+    class POIInfoWindow extends DefaultInfoWindow {
+
+        private Button mButton;
+        private ImageView mImage;
+
+        public POIInfoWindow(Map map) {
+            super(R.layout.bonuspack_bubble, App.view);
+
+            mButton = (Button) mView.findViewById(R.id.bubble_moreinfo);
+            mImage = (ImageView) mView.findViewById(R.id.bubble_image);
+
+            //bonuspack_bubble layouts already contain a "more info" button.
+            mButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    POI poi = (POI) view.getTag();
+
+                    if (poi == null)
+                        return;
+
+                    if (poi.serviceId == POI.POI_SERVICE_4SQUARE) {
+                        FourSquareProvider.browse(view.getContext(), poi);
+                    } else if (poi.url != null) {
+                        Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(poi.url));
+                        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+                        view.getContext().startActivity(i);
+                    }
+                }
+            });
+
+            getView().setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    POI poi = (POI) view.getTag();
+
+                    if (poi != null)
+                        showPOIActivity(false);
+                }
+            });
+        }
+
+        @Override
+        public void onOpen(ExtendedMarkerItem item) {
+            POI poi = (POI) item.getRelatedObject();
+
+            super.onOpen(item);
+
+            poi.fetchThumbnail(mImage);
+
+            //Show or hide "more info" button:
+            if (poi.url != null)
+                mButton.setVisibility(View.VISIBLE);
+            else
+                mButton.setVisibility(View.GONE);
+
+            mButton.setTag(poi);
+            getView().setTag(poi);
+        }
+    }
+
+    public boolean onContextItemSelected(MenuItem item, GeoPoint geoPoint) {
+        switch (item.getItemId()) {
+            case R.id.menu_poi_nearby:
+                Intent intent = new Intent(App.activity, POIActivity.class);
+                intent.putExtra("ID", poiMarkers.getBubbledItemId());
+                App.activity.startActivityForResult(intent, TileMap.POIS_REQUEST);
+                return true;
+
+            case R.id.menu_poi_clear:
+                poiMarkers.removeAllItems();
+                mPOIs.clear();
+                App.map.updateMap(true);
+
+                return true;
+            default:
+        }
+        return false;
+
+    }
+
+}
diff --git a/vtm-app/src/org/oscim/app/RouteSearch.java b/vtm-app/src/org/oscim/app/RouteSearch.java
new file mode 100644
index 00000000..667f9e4d
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/RouteSearch.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright 2012 osmdroid: M.Kergall
+ * Copyright 2012 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app;
+
+import android.app.Activity;
+import android.location.Address;
+import android.os.AsyncTask;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import org.oscim.android.canvas.AndroidGraphics;
+import org.oscim.core.GeoPoint;
+import org.oscim.layers.PathLayer;
+import org.oscim.layers.marker.MarkerItem.HotspotPlace;
+import org.oscim.layers.marker.MarkerSymbol;
+import org.osmdroid.location.GeocoderNominatim;
+import org.osmdroid.overlays.DefaultInfoWindow;
+import org.osmdroid.overlays.ExtendedMarkerItem;
+import org.osmdroid.overlays.ItemizedOverlayWithBubble;
+import org.osmdroid.routing.Route;
+import org.osmdroid.routing.RouteProvider;
+import org.osmdroid.routing.provider.OSRMRouteProvider;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+public class RouteSearch {
+    private static int START_INDEX = -2, DEST_INDEX = -1;
+
+    private final PathLayer mRouteOverlay;
+    //private final ItemizedOverlayWithBubble<ExtendedOverlayItem> mRouteMarkers;
+    private final ItemizedOverlayWithBubble<ExtendedMarkerItem> mItineraryMarkers;
+
+    private final RouteBar mRouteBar;
+
+    private GeoPoint mStartPoint, mDestinationPoint;
+    private final ArrayList<GeoPoint> mViaPoints;
+
+    private ExtendedMarkerItem markerStart, markerDestination;
+
+    private UpdateRouteTask mRouteTask;
+
+    RouteSearch() {
+        mViaPoints = new ArrayList<GeoPoint>();
+
+        // Itinerary markers:
+        ArrayList<ExtendedMarkerItem> waypointsItems = new ArrayList<ExtendedMarkerItem>();
+
+        mItineraryMarkers = new ItemizedOverlayWithBubble<ExtendedMarkerItem>(App.map,
+                App.activity,
+                null,
+                waypointsItems,
+                new ViaPointInfoWindow(R.layout.itinerary_bubble));
+
+        //updateIternaryMarkers();
+
+        //Route and Directions
+        //ArrayList<ExtendedOverlayItem> routeItems = new ArrayList<ExtendedOverlayItem>();
+        //mRouteMarkers = new ItemizedOverlayWithBubble<ExtendedOverlayItem>(App.map, App.activity,
+        //        null, routeItems);
+
+        mRouteOverlay = new PathLayer(App.map, 0xAA0000FF, 3);
+
+        // TODO use LayerGroup
+        App.map.layers().add(mRouteOverlay);
+        //App.map.getOverlays().add(mRouteMarkers);
+        App.map.layers().add(mItineraryMarkers);
+
+        mRouteBar = new RouteBar(App.activity);
+    }
+
+    /**
+     * Retrieve route between p1 and p2 and update overlays.
+     */
+    public void showRoute(GeoPoint p1, GeoPoint p2) {
+        clearOverlays();
+
+        mStartPoint = p1;
+        markerStart = putMarkerItem(markerStart, mStartPoint, START_INDEX,
+                R.string.departure, R.drawable.marker_departure, -1);
+
+        mDestinationPoint = p2;
+        markerDestination = putMarkerItem(markerDestination, mDestinationPoint, DEST_INDEX,
+                R.string.destination,
+                R.drawable.marker_destination, -1);
+
+        getRouteAsync();
+    }
+
+    /**
+     * Reverse Geocoding
+     */
+    public String getAddress(GeoPoint p) {
+        GeocoderNominatim geocoder = new GeocoderNominatim(App.activity);
+        String theAddress;
+        try {
+            double dLatitude = p.getLatitude();
+            double dLongitude = p.getLongitude();
+            List<Address> addresses = geocoder.getFromLocation(dLatitude, dLongitude, 1);
+            StringBuilder sb = new StringBuilder();
+            if (addresses.size() > 0) {
+                Address address = addresses.get(0);
+                int n = address.getMaxAddressLineIndex();
+                for (int i = 0; i <= n; i++) {
+                    if (i != 0)
+                        sb.append(", ");
+                    sb.append(address.getAddressLine(i));
+                }
+                theAddress = new String(sb.toString());
+            } else {
+                theAddress = null;
+            }
+        } catch (IOException e) {
+            theAddress = null;
+        }
+        if (theAddress != null) {
+            return theAddress;
+        }
+        return "";
+    }
+
+    // Async task to reverse-geocode the marker position in a separate thread:
+    class GeocodingTask extends AsyncTask<Object, Void, String> {
+        ExtendedMarkerItem marker;
+
+        @Override
+        protected String doInBackground(Object... params) {
+            marker = (ExtendedMarkerItem) params[0];
+            return getAddress(marker.getPoint());
+        }
+
+        @Override
+        protected void onPostExecute(String result) {
+            marker.setDescription(result);
+        }
+    }
+
+    /* add (or replace) an item in markerOverlays. p position. */
+    public ExtendedMarkerItem putMarkerItem(ExtendedMarkerItem item, GeoPoint p, int index,
+                                            int titleResId, int markerResId, int iconResId) {
+
+        if (item != null)
+            mItineraryMarkers.removeItem(item);
+
+        MarkerSymbol marker = AndroidGraphics.makeMarker(App.res.getDrawable(markerResId),
+                HotspotPlace.BOTTOM_CENTER);
+
+        ExtendedMarkerItem overlayItem =
+                new ExtendedMarkerItem(App.res.getString(titleResId), "", p);
+
+        overlayItem.setMarker(marker);
+
+        if (iconResId != -1)
+            overlayItem.setImage(App.res.getDrawable(iconResId));
+
+        overlayItem.setRelatedObject(Integer.valueOf(index));
+
+        mItineraryMarkers.addItem(overlayItem);
+
+        App.map.updateMap(true);
+
+        //Start geocoding task to update the description of the marker with its address:
+        new GeocodingTask().execute(overlayItem);
+
+        return overlayItem;
+    }
+
+    public void addViaPoint(GeoPoint p) {
+        mViaPoints.add(p);
+        putMarkerItem(null, p, mViaPoints.size() - 1,
+                R.string.viapoint, R.drawable.marker_via, -1);
+    }
+
+    public void removePoint(int index) {
+        if (index == START_INDEX) {
+            mStartPoint = null;
+        } else if (index == DEST_INDEX) {
+            mDestinationPoint = null;
+        } else
+            mViaPoints.remove(index);
+
+        getRouteAsync();
+        updateIternaryMarkers();
+    }
+
+    public void updateIternaryMarkers() {
+        mItineraryMarkers.removeAllItems();
+
+        //Start marker:
+        if (mStartPoint != null) {
+            markerStart = putMarkerItem(null, mStartPoint, START_INDEX,
+                    R.string.departure, R.drawable.marker_departure, -1);
+        }
+        //Via-points markers if any:
+        for (int index = 0; index < mViaPoints.size(); index++) {
+            putMarkerItem(null, mViaPoints.get(index), index,
+                    R.string.viapoint, R.drawable.marker_via, -1);
+        }
+        //Destination marker if any:
+        if (mDestinationPoint != null) {
+            markerDestination = putMarkerItem(null, mDestinationPoint, DEST_INDEX,
+                    R.string.destination,
+                    R.drawable.marker_destination, -1);
+        }
+    }
+
+    //------------ Route and Directions
+    private void updateOverlays(Route route) {
+        //mRouteMarkers.removeAllItems();
+
+        mRouteOverlay.clearPath();
+
+        if (route == null || route.status == Route.STATUS_DEFAULT) {
+            App.activity.showToastOnUiThread(App.res.getString(R.string.route_lookup_error));
+            return;
+        }
+
+        mRouteOverlay.setPoints(route.routeHigh);
+
+        //OverlayMarker marker = AndroidGraphics.makeMarker(App.res, R.drawable.marker_node, null);
+
+        //int n = route.nodes.size();
+        //for (int i = 0; i < n; i++) {
+        //    RouteNode node = route.nodes.get(i);
+        //    String instructions = (node.instructions == null ? "" : node.instructions);
+        //    ExtendedOverlayItem nodeMarker = new ExtendedOverlayItem(
+        //            "Step " + (i + 1), instructions, node.location);
+        //
+        //    nodeMarker.setSubDescription(route.getLengthDurationText(node.length, node.duration));
+        //    nodeMarker.setMarkerHotspot(OverlayItem.HotspotPlace.CENTER);
+        //    nodeMarker.setMarker(marker);
+        //
+        //    mRouteMarkers.addItem(nodeMarker);
+        //}
+
+        App.map.updateMap(true);
+    }
+
+    void clearOverlays() {
+        //mRouteMarkers.removeAllItems(true);
+        mItineraryMarkers.removeAllItems(true);
+
+        mRouteOverlay.clearPath();
+        mStartPoint = null;
+        mDestinationPoint = null;
+        mViaPoints.clear();
+
+        App.map.updateMap(true);
+    }
+
+    /**
+     * Async task to get the route in a separate thread.
+     */
+    class UpdateRouteTask extends AsyncTask<List<GeoPoint>, Void, Route> {
+        @Override
+        protected Route doInBackground(List<GeoPoint>... wp) {
+            List<GeoPoint> waypoints = wp[0];
+
+            //RouteProvider routeProvider = new MapQuestRouteProvider();
+            //Locale locale = Locale.getDefault();
+            //routeProvider.addRequestOption("locale=" + locale.getLanguage() + "_"
+            //        + locale.getCountry());
+            //routeProvider.addRequestOption("routeType=pedestrian");
+
+            //RouteProvider routeProvider = new GoogleRouteProvider();
+            RouteProvider routeProvider = new OSRMRouteProvider();
+            return routeProvider.getRoute(waypoints);
+        }
+
+        @Override
+        protected void onPostExecute(Route result) {
+
+            updateOverlays(result);
+            mRouteBar.set(result);
+
+            mRouteTask = null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void getRouteAsync() {
+        if (mRouteTask != null) {
+            mRouteTask.cancel(true);
+            mRouteTask = null;
+        }
+
+        if (mStartPoint == null || mDestinationPoint == null) {
+            mRouteOverlay.clearPath();
+            return;
+        }
+
+        List<GeoPoint> waypoints = new ArrayList<GeoPoint>();
+        waypoints.add(mStartPoint);
+        //add intermediate via points:
+        for (GeoPoint p : mViaPoints) {
+            waypoints.add(p);
+        }
+        waypoints.add(mDestinationPoint);
+
+        mRouteTask = new UpdateRouteTask();
+        mRouteTask.execute(waypoints);
+    }
+
+    boolean onContextItemSelected(MenuItem item, GeoPoint geoPoint) {
+        switch (item.getItemId()) {
+            case R.id.menu_route_departure:
+                mStartPoint = geoPoint;
+
+                markerStart = putMarkerItem(markerStart, mStartPoint, START_INDEX,
+                        R.string.departure, R.drawable.marker_departure, -1);
+
+                getRouteAsync();
+                return true;
+
+            case R.id.menu_route_destination:
+                mDestinationPoint = geoPoint;
+
+                markerDestination = putMarkerItem(markerDestination, mDestinationPoint, DEST_INDEX,
+                        R.string.destination,
+                        R.drawable.marker_destination, -1);
+
+                getRouteAsync();
+                return true;
+
+            case R.id.menu_route_viapoint:
+                GeoPoint viaPoint = geoPoint;
+                addViaPoint(viaPoint);
+
+                getRouteAsync();
+                return true;
+
+            case R.id.menu_route_clear:
+                clearOverlays();
+                return true;
+
+            default:
+        }
+        return false;
+    }
+
+    public boolean isEmpty() {
+        return (mItineraryMarkers.size() == 0);
+    }
+
+    class ViaPointInfoWindow extends DefaultInfoWindow {
+
+        int mSelectedPoint;
+
+        public ViaPointInfoWindow(int layoutResId) {
+            super(layoutResId, App.view);
+
+            Button btnDelete = (Button) (mView.findViewById(R.id.bubble_delete));
+            btnDelete.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    removePoint(mSelectedPoint);
+                    close();
+                }
+            });
+        }
+
+        @Override
+        public void onOpen(ExtendedMarkerItem item) {
+            mSelectedPoint = ((Integer) item.getRelatedObject()).intValue();
+            super.onOpen(item);
+        }
+    }
+
+    class RouteBar {
+
+        TextView mDistance = null;
+        TextView mRouteLength = null;
+        TextView mTravelTime = null;
+        ImageView mClearButton = null;
+        RelativeLayout mRouteBarView = null;
+
+        RouteBar(Activity activity) {
+
+            mRouteBarView = (RelativeLayout) activity.findViewById(R.id.route_bar);
+            mDistance = (TextView) activity.findViewById(R.id.route_bar_distance);
+            mRouteLength = (TextView) activity.findViewById(R.id.route_bar_route_length);
+            mTravelTime = (TextView) activity.findViewById(R.id.route_bar_travel_time);
+
+            mClearButton = (ImageView) activity.findViewById(R.id.route_bar_clear);
+
+            mRouteBarView.setVisibility(View.INVISIBLE);
+
+            mClearButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    mRouteBarView.setVisibility(View.INVISIBLE);
+                    clearOverlays();
+                }
+            });
+        }
+
+        public void set(Route result) {
+            DecimalFormat twoDForm = new DecimalFormat("#.#");
+            DecimalFormat oneDForm = new DecimalFormat("#");
+            int hour = ((int) result.duration / 3600);
+            int minute = ((int) result.duration % 3600) / 60;
+            String time = "";
+            if (hour == 0 && minute == 0) {
+                time = "?";
+            } else if (hour == 0 && minute != 0) {
+                time = minute + "m";
+            } else {
+                time = hour + "h " + minute + "m";
+            }
+
+            double dis = ((double) (mStartPoint.distanceTo(mDestinationPoint))) / 1000;
+            String distance;
+            String shortpath;
+            if (dis < 100) {
+                distance = twoDForm.format(dis);
+            } else {
+                distance = oneDForm.format(dis);
+            }
+            if (result.length == 0) {
+                shortpath = "?";
+            } else if (result.length < 100) {
+                shortpath = twoDForm.format(result.length);
+            } else {
+                shortpath = oneDForm.format(result.length);
+            }
+
+            mRouteBarView.setVisibility(View.VISIBLE);
+            mDistance.setText(distance + " km");
+            mTravelTime.setText(time);
+            mRouteLength.setText(shortpath + " km");
+        }
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/TileMap.java b/vtm-app/src/org/oscim/app/TileMap.java
new file mode 100755
index 00000000..8d2e5a2d
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/TileMap.java
@@ -0,0 +1,518 @@
+/* Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2012 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.oscim.app;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.preference.PreferenceManager;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+import org.oscim.android.MapView;
+import org.oscim.app.location.Compass;
+import org.oscim.app.location.LocationDialog;
+import org.oscim.app.location.LocationHandler;
+import org.oscim.app.preferences.EditPreferences;
+import org.oscim.core.GeoPoint;
+import org.oscim.overlay.DistanceTouchOverlay;
+import org.osmdroid.location.POI;
+import org.osmdroid.overlays.MapEventsReceiver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public class TileMap extends MapActivity implements MapEventsReceiver {
+    final static Logger log = LoggerFactory.getLogger(TileMap.class);
+
+    private static final int DIALOG_ENTER_COORDINATES = 0;
+    private static final int DIALOG_LOCATION_PROVIDER_DISABLED = 2;
+
+    //private static final int SELECT_RENDER_THEME_FILE = 1;
+    protected static final int POIS_REQUEST = 2;
+
+    private LocationHandler mLocation;
+    private Compass mCompass;
+
+    private Menu mMenu = null;
+    private MapLayers mMapLayers;
+
+    public MapLayers getMapLayers() {
+        return mMapLayers;
+    }
+
+    private DistanceTouchOverlay mDistanceTouch;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.activity_tilemap);
+        App.view = (MapView) findViewById(R.id.mapView);
+        registerMapView(App.view);
+
+        App.map = mMap;
+        App.activity = this;
+
+        mMapLayers = new MapLayers();
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+        mMapLayers.setBaseMap(prefs);
+
+        if (!prefs.contains("distanceTouch"))
+            prefs.edit().putBoolean("distanceTouch", true).apply();
+
+        if (prefs.getBoolean("distanceTouch", true)) {
+            mDistanceTouch = new DistanceTouchOverlay(mMap, this);
+            mMap.layers().add(mDistanceTouch);
+        }
+
+        mCompass = new Compass(this, mMap);
+        mMap.layers().add(mCompass);
+
+        mLocation = new LocationHandler(this, mCompass);
+
+        App.poiSearch = new POISearch();
+        App.routeSearch = new RouteSearch();
+
+        registerForContextMenu(App.view);
+
+        handleIntent(getIntent(), true);
+    }
+
+    public Compass getCompass() {
+        return mCompass;
+    }
+
+    public LocationHandler getLocationHandler() {
+        return mLocation;
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        handleIntent(intent, false);
+    }
+
+    private void handleIntent(Intent intent, boolean start) {
+        if (intent == null)
+            return;
+
+        Uri uri = intent.getData();
+        if (uri != null) {
+            String scheme = uri.getSchemeSpecificPart();
+            log.debug("got intent: " + (scheme == null ? "" : scheme));
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.options_menu, menu);
+        mMenu = menu;
+        toggleMenuCheck();
+        return true;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+        switch (item.getItemId()) {
+            case R.id.menu_info_about:
+                startActivity(new Intent(this, InfoView.class));
+                break;
+
+            case R.id.menu_position:
+                break;
+
+            case R.id.menu_poi_nearby:
+                Intent intent = new Intent(this, POIActivity.class);
+                startActivityForResult(intent, TileMap.POIS_REQUEST);
+                break;
+
+            case R.id.menu_compass_2d:
+                if (!item.isChecked()) {
+                    // FIXME
+                    //mMapView.getMapViewPosition().setTilt(0);
+                    mCompass.setMode(Compass.Mode.C2D);
+                } else {
+                    mCompass.setMode(Compass.Mode.OFF);
+                }
+                break;
+
+            case R.id.menu_compass_3d:
+                if (!item.isChecked()) {
+                    mCompass.setMode(Compass.Mode.C3D);
+                } else {
+                    mCompass.setMode(Compass.Mode.OFF);
+                }
+                break;
+
+            case R.id.menu_position_my_location_enable:
+                if (!item.isChecked()) {
+                    mLocation.setMode(LocationHandler.Mode.SHOW);
+                    mLocation.setCenterOnFirstFix();
+                } else {
+                    mLocation.setMode(LocationHandler.Mode.OFF);
+                }
+                break;
+
+            case R.id.menu_position_follow_location:
+                if (!item.isChecked()) {
+                    mLocation.setMode(LocationHandler.Mode.SNAP);
+                } else {
+                    mLocation.setMode(LocationHandler.Mode.OFF);
+                }
+                break;
+
+            case R.id.menu_layer_openstreetmap:
+            case R.id.menu_layer_naturalearth:
+                int bgId = item.getItemId();
+                // toggle if already enabled
+                if (bgId == mMapLayers.getBackgroundId())
+                    bgId = -1;
+
+                mMapLayers.setBackgroundMap(bgId);
+                mMap.updateMap(true);
+                break;
+
+            case R.id.menu_layer_grid:
+                mMapLayers.enableGridOverlay(!mMapLayers.isGridEnabled());
+                mMap.updateMap(true);
+                break;
+
+            case R.id.menu_position_enter_coordinates:
+                showDialog(DIALOG_ENTER_COORDINATES);
+                break;
+
+            //case R.id.menu_position_map_center:
+            //    MapPosition mapCenter = mBaseLayer.getMapFileCenter();
+            //    if (mapCenter != null)
+            //        mMap.setCenter(mapCenter.getGeoPoint());
+            //    break;
+
+            case R.id.menu_preferences:
+                startActivity(new Intent(this, EditPreferences.class));
+                overridePendingTransition(R.anim.slide_right, R.anim.slide_left2);
+                break;
+
+            default:
+                return false;
+        }
+
+        toggleMenuCheck();
+
+        return true;
+    }
+
+    private void toggleMenuCheck() {
+
+        mMenu.findItem(R.id.menu_compass_2d)
+                .setChecked(mCompass.getMode() == Compass.Mode.C2D);
+        mMenu.findItem(R.id.menu_compass_3d)
+                .setChecked(mCompass.getMode() == Compass.Mode.C3D);
+
+        mMenu.findItem(R.id.menu_position_my_location_enable)
+                .setChecked(mLocation.getMode() == LocationHandler.Mode.SHOW);
+        mMenu.findItem(R.id.menu_position_follow_location)
+                .setChecked(mLocation.getMode() == LocationHandler.Mode.SNAP);
+
+        int bgId = mMapLayers.getBackgroundId();
+        mMenu.findItem(R.id.menu_layer_naturalearth)
+                .setChecked(bgId == R.id.menu_layer_naturalearth);
+
+        mMenu.findItem(R.id.menu_layer_openstreetmap)
+                .setChecked(bgId == R.id.menu_layer_openstreetmap);
+
+        mMenu.findItem(R.id.menu_layer_grid)
+                .setChecked(mMapLayers.isGridEnabled());
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+
+        if (!isPreHoneyComb()) {
+            menu.clear();
+            onCreateOptionsMenu(menu);
+        }
+
+        menu.findItem(R.id.menu_position_map_center).setVisible(false);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        switch (requestCode) {
+            case POIS_REQUEST:
+                log.debug("result: POIS_REQUEST");
+                if (resultCode == RESULT_OK) {
+                    int id = intent.getIntExtra("ID", 0);
+                    log.debug("result: POIS_REQUEST: " + id);
+
+                    App.poiSearch.poiMarkers.showBubbleOnItem(id);
+                    POI poi = App.poiSearch.getPOIs().get(id);
+
+                    if (poi.bbox != null)
+                        mMap.animator().animateTo(poi.bbox);
+                    else
+                        mMap.animator().animateTo(poi.location);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    static boolean isPreHoneyComb() {
+        return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        if (id == DIALOG_ENTER_COORDINATES) {
+            if (mLocationDialog == null)
+                mLocationDialog = new LocationDialog();
+
+            return mLocationDialog.createDialog(this);
+
+        } else if (id == DIALOG_LOCATION_PROVIDER_DISABLED) {
+            builder.setIcon(android.R.drawable.ic_menu_info_details);
+            builder.setTitle(R.string.error);
+            builder.setMessage(R.string.no_location_provider_available);
+            builder.setPositiveButton(R.string.ok, null);
+            return builder.create();
+        } else {
+            // no dialog will be created
+            return null;
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mCompass.pause();
+        mLocation.pause();
+    }
+
+    LocationDialog mLocationDialog;
+
+    @SuppressWarnings("deprecation")
+    @Override
+    protected void onPrepareDialog(int id, final Dialog dialog) {
+        if (id == DIALOG_ENTER_COORDINATES) {
+
+            mLocationDialog.prepareDialog(mMap, dialog);
+
+        } else {
+            super.onPrepareDialog(id, dialog);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        mCompass.resume();
+        mLocation.resume();
+
+        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+        mMapLayers.setPreferences(preferences);
+
+        if (preferences.getBoolean("fullscreen", false)) {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        } else {
+            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        }
+
+        App.lockOrientation(this);
+
+        boolean distanceTouch = preferences.getBoolean("distanceTouch", true);
+        if (distanceTouch) {
+            if (mDistanceTouch == null) {
+                mDistanceTouch = new DistanceTouchOverlay(mMap, this);
+                mMap.layers().add(mDistanceTouch);
+            }
+        } else {
+            mMap.layers().remove(mDistanceTouch);
+            mDistanceTouch = null;
+        }
+
+        mMap.updateMap(true);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+    }
+
+    /**
+     * Uses the UI thread to display the given text message as toast
+     * notification.
+     *
+     * @param text the text message to display
+     */
+    public void showToastOnUiThread(final String text) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast toast = Toast.makeText(TileMap.this, text, Toast.LENGTH_SHORT);
+                toast.show();
+            }
+        });
+    }
+
+    private enum Mode {
+        DEFAULT,
+        SHOW_LOCATION,
+        SNAP_LOCATION,
+        COMPASS_2D,
+        COMPASS_3D,
+    }
+
+    private int mMapMode = 0;
+
+    public void toggleLocation(View V) {
+
+        ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(50);
+
+        mMapMode += 1;
+        mMapMode %= Mode.values().length;
+
+        setInteractionMode(mMapMode);
+    }
+
+    private void setInteractionMode(int mapMode) {
+        Mode m = Mode.values()[mapMode];
+
+        switch (m) {
+            case DEFAULT:
+
+                mLocation.setMode(LocationHandler.Mode.OFF);
+                mCompass.setMode(Compass.Mode.OFF);
+
+                App.activity.showToastOnUiThread("Manual");
+
+                break;
+            case SHOW_LOCATION:
+                mLocation.setMode(LocationHandler.Mode.SHOW);
+                mCompass.setMode(Compass.Mode.OFF);
+                App.activity.showToastOnUiThread(App.activity
+                        .getString(R.string.menu_position_my_location_enable));
+                break;
+
+            case SNAP_LOCATION:
+                mLocation.setMode(LocationHandler.Mode.SNAP);
+                mCompass.setMode(Compass.Mode.OFF);
+                App.activity.showToastOnUiThread(App.activity
+                        .getString(R.string.menu_position_follow_location));
+                break;
+
+            case COMPASS_2D:
+                // FIXME
+                //mMapView.getMapViewPosition().setTilt(0);
+
+                mLocation.setMode(LocationHandler.Mode.SHOW);
+                mCompass.setMode(Compass.Mode.C2D);
+                App.activity.showToastOnUiThread("Compass 2D");
+                break;
+
+            case COMPASS_3D:
+                mLocation.setMode(LocationHandler.Mode.SHOW);
+                mCompass.setMode(Compass.Mode.C3D);
+                App.activity.showToastOnUiThread("Compass 3D");
+                break;
+
+            default:
+                break;
+        }
+
+        App.map.updateMap(true);
+    }
+
+    /**
+     * Context Menu when clicking on the {@link Map}
+     */
+    private GeoPoint mLongPressGeoPoint;
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        super.onCreateContextMenu(menu, v, menuInfo);
+
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.map_menu, menu);
+
+        if (App.poiSearch.getPOIs().isEmpty())
+            menu.removeItem(R.id.menu_poi_clear);
+
+        if (App.routeSearch.isEmpty())
+            menu.removeItem(R.id.menu_route_clear);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        if (App.poiSearch.onContextItemSelected(item, mLongPressGeoPoint))
+            return true;
+
+        if (App.routeSearch.onContextItemSelected(item, mLongPressGeoPoint))
+            return true;
+
+        return super.onContextItemSelected(item);
+    }
+
+    /**
+     * MapEventsReceiver implementation
+     */
+    @Override
+    public boolean singleTapUpHelper(GeoPoint p) {
+        return false;
+    }
+
+    @Override
+    public boolean longPressHelper(GeoPoint p) {
+        mLongPressGeoPoint = p;
+        openContextMenu(App.view);
+        return true;
+    }
+
+    @Override
+    public boolean longPressHelper(final GeoPoint p1, final GeoPoint p2) {
+        ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(50);
+        showToastOnUiThread("Distance Touch!");
+        App.routeSearch.showRoute(p1, p2);
+        return true;
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/filefilter/FilterByFileExtension.java b/vtm-app/src/org/oscim/app/filefilter/FilterByFileExtension.java
new file mode 100644
index 00000000..75a3c60a
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/filefilter/FilterByFileExtension.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.filefilter;
+
+import java.io.File;
+import java.io.FileFilter;
+
+/**
+ * Accepts all readable directories and all readable files with a given
+ * extension.
+ */
+public class FilterByFileExtension implements FileFilter {
+    private final String extension;
+
+    /**
+     * @param extension the allowed file name extension.
+     */
+    public FilterByFileExtension(String extension) {
+        this.extension = extension;
+    }
+
+    @Override
+    public boolean accept(File file) {
+        // accept only readable files
+        if (file.canRead()) {
+            if (file.isDirectory()) {
+                // accept all directories
+                return true;
+            } else if (file.isFile() && file.getName().endsWith(this.extension)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/filefilter/ValidFileFilter.java b/vtm-app/src/org/oscim/app/filefilter/ValidFileFilter.java
new file mode 100644
index 00000000..2c9e12d5
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/filefilter/ValidFileFilter.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.filefilter;
+
+import org.oscim.tiling.TileSource.OpenResult;
+
+import java.io.FileFilter;
+
+/**
+ * An extension of the {@link FileFilter} interface.
+ */
+public interface ValidFileFilter extends FileFilter {
+    /**
+     * @return the result of the last {@link #accept} call (might be null).
+     */
+    OpenResult getFileOpenResult();
+}
diff --git a/vtm-app/src/org/oscim/app/filefilter/ValidMapFile.java b/vtm-app/src/org/oscim/app/filefilter/ValidMapFile.java
new file mode 100644
index 00000000..761a9c35
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/filefilter/ValidMapFile.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.filefilter;
+
+import org.oscim.tiling.TileSource.OpenResult;
+import org.oscim.tiling.source.mapfile.MapFileTileSource;
+
+import java.io.File;
+
+/**
+ * Accepts all valid map files.
+ */
+public final class ValidMapFile implements ValidFileFilter {
+    private OpenResult openResult;
+
+    @Override
+    public boolean accept(File file) {
+        MapFileTileSource mapFileSource = new MapFileTileSource();
+        mapFileSource.setMapFile(file.getAbsolutePath());
+
+        this.openResult = mapFileSource.open();
+        mapFileSource.close();
+        return this.openResult.isSuccess();
+    }
+
+    @Override
+    public OpenResult getFileOpenResult() {
+        return this.openResult;
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java b/vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java
new file mode 100644
index 00000000..052eea4a
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2016 devemux86
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.filefilter;
+
+import org.oscim.theme.XmlThemeBuilder;
+import org.oscim.tiling.TileSource.OpenResult;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * Accepts all valid render theme XML files.
+ */
+public final class ValidRenderTheme implements ValidFileFilter {
+    private OpenResult openResult;
+
+    @Override
+    public boolean accept(File file) {
+        InputStream inputStream = null;
+
+        try {
+            inputStream = new FileInputStream(file);
+            XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(file.getParent());
+            XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+            xmlReader.setContentHandler(renderThemeHandler);
+            xmlReader.parse(new InputSource(inputStream));
+            this.openResult = OpenResult.SUCCESS;
+        } catch (ParserConfigurationException e) {
+            this.openResult = new OpenResult(e.getMessage());
+        } catch (SAXException e) {
+            this.openResult = new OpenResult(e.getMessage());
+        } catch (IOException e) {
+            this.openResult = new OpenResult(e.getMessage());
+        } finally {
+            try {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            } catch (IOException e) {
+                this.openResult = new OpenResult(e.getMessage());
+            }
+        }
+
+        return this.openResult.isSuccess();
+    }
+
+    @Override
+    public OpenResult getFileOpenResult() {
+        return this.openResult;
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/filepicker/FilePicker.java b/vtm-app/src/org/oscim/app/filepicker/FilePicker.java
new file mode 100755
index 00000000..764e3514
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/filepicker/FilePicker.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.filepicker;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.GridView;
+
+import org.oscim.app.R;
+import org.oscim.app.filefilter.ValidFileFilter;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * A FilePicker displays the contents of directories. The user can navigate
+ * within the file system and select a single
+ * file whose path is then returned to the calling activity. The ordering of
+ * directory contents can be specified via
+ * {@link #setFileComparator(Comparator)}. By default subfolders and files are
+ * grouped and each group is ordered
+ * alphabetically.
+ * <p/>
+ * A {@link FileFilter} can be activated via
+ * {@link #setFileDisplayFilter(FileFilter)} to restrict the displayed files and
+ * folders. By default all files and folders are visible.
+ * <p/>
+ * Another <code>FileFilter</code> can be applied via
+ * {@link #setFileSelectFilter(ValidFileFilter)} to check if a selected file is
+ * valid before its path is returned. By default all files are considered as
+ * valid and can be selected.
+ */
+public class FilePicker extends Activity implements AdapterView.OnItemClickListener {
+    /**
+     * The name of the extra data in the result {@link Intent}.
+     */
+    public static final String SELECTED_FILE = "selectedFile";
+
+    private static final String CURRENT_DIRECTORY = "currentDirectory";
+    private static final String DEFAULT_DIRECTORY = "/";
+    private static final int DIALOG_FILE_INVALID = 0;
+    // private static final int DIALOG_FILE_SELECT = 1;
+    private static Comparator<File> fileComparator = getDefaultFileComparator();
+    private static FileFilter fileDisplayFilter;
+    private static ValidFileFilter fileSelectFilter;
+    private static final String PREFERENCES_FILE = "FilePicker";
+
+    /**
+     * Sets the file comparator which is used to order the contents of all
+     * directories before displaying them. If set to
+     * null, subfolders and files will not be ordered.
+     *
+     * @param fileComparator the file comparator (may be null).
+     */
+    public static void setFileComparator(Comparator<File> fileComparator) {
+        FilePicker.fileComparator = fileComparator;
+    }
+
+    /**
+     * Sets the file display filter. This filter is used to determine which
+     * files and subfolders of directories will be
+     * displayed. If set to null, all files and subfolders are shown.
+     *
+     * @param fileDisplayFilter the file display filter (may be null).
+     */
+    public static void setFileDisplayFilter(FileFilter fileDisplayFilter) {
+        FilePicker.fileDisplayFilter = fileDisplayFilter;
+    }
+
+    /**
+     * Sets the file select filter. This filter is used when the user selects a
+     * file to determine if it is valid. If set
+     * to null, all files are considered as valid.
+     *
+     * @param fileSelectFilter the file selection filter (may be null).
+     */
+    public static void setFileSelectFilter(ValidFileFilter fileSelectFilter) {
+        FilePicker.fileSelectFilter = fileSelectFilter;
+    }
+
+    /**
+     * Creates the default file comparator.
+     *
+     * @return the default file comparator.
+     */
+    private static Comparator<File> getDefaultFileComparator() {
+        // order all files by type and alphabetically by name
+        return new Comparator<File>() {
+            @Override
+            public int compare(File file1, File file2) {
+                if (file1.isDirectory() && !file2.isDirectory()) {
+                    return -1;
+                } else if (!file1.isDirectory() && file2.isDirectory()) {
+                    return 1;
+                } else {
+                    return file1.getName().compareToIgnoreCase(file2.getName());
+                }
+            }
+        };
+    }
+
+    private File currentDirectory;
+    private FilePickerIconAdapter filePickerIconAdapter;
+    private File[] files;
+    private File[] filesWithParentFolder;
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        File selectedFile = this.files[(int) id];
+        if (selectedFile.isDirectory()) {
+            this.currentDirectory = selectedFile;
+            browseToCurrentDirectory();
+        } else if (fileSelectFilter == null || fileSelectFilter.accept(selectedFile)) {
+            setResult(RESULT_OK,
+                    new Intent().putExtra(SELECTED_FILE, selectedFile.getAbsolutePath()));
+            finish();
+        } else {
+            showDialog(DIALOG_FILE_INVALID);
+        }
+    }
+
+    /**
+     * Browses to the current directory.
+     */
+    private void browseToCurrentDirectory() {
+        setTitle(this.currentDirectory.getAbsolutePath());
+
+        // read the subfolders and files from the current directory
+        if (fileDisplayFilter == null) {
+            this.files = this.currentDirectory.listFiles();
+        } else {
+            this.files = this.currentDirectory.listFiles(fileDisplayFilter);
+        }
+
+        if (this.files == null) {
+            this.files = new File[0];
+        } else {
+            // order the subfolders and files
+            Arrays.sort(this.files, fileComparator);
+        }
+
+        // if a parent directory exists, add it at the first position
+        if (this.currentDirectory.getParentFile() != null) {
+            this.filesWithParentFolder = new File[this.files.length + 1];
+            this.filesWithParentFolder[0] = this.currentDirectory.getParentFile();
+            System.arraycopy(this.files, 0, this.filesWithParentFolder, 1,
+                    this.files.length);
+            this.files = this.filesWithParentFolder;
+            this.filePickerIconAdapter.setFiles(this.files, true);
+        } else {
+            this.filePickerIconAdapter.setFiles(this.files, false);
+        }
+        this.filePickerIconAdapter.notifyDataSetChanged();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_file_picker);
+
+        this.filePickerIconAdapter = new FilePickerIconAdapter(this);
+        GridView gridView = (GridView) findViewById(R.id.filePickerView);
+        gridView.setOnItemClickListener(this);
+        gridView.setAdapter(this.filePickerIconAdapter);
+
+        // if (savedInstanceState == null) {
+        // // first start of this instance
+        // showDialog(DIALOG_FILE_SELECT);
+        // }
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        switch (id) {
+            case DIALOG_FILE_INVALID:
+                builder.setIcon(android.R.drawable.ic_menu_info_details);
+                builder.setTitle(R.string.error);
+
+                StringBuilder stringBuilder = new StringBuilder();
+                stringBuilder.append(getString(R.string.file_invalid));
+                stringBuilder.append("\n\n");
+                stringBuilder.append(FilePicker.fileSelectFilter.getFileOpenResult()
+                        .getErrorMessage());
+
+                builder.setMessage(stringBuilder.toString());
+                builder.setPositiveButton(R.string.ok, null);
+                return builder.create();
+            // case DIALOG_FILE_SELECT:
+            // builder.setMessage(R.string.file_select);
+            // builder.setPositiveButton(R.string.ok, null);
+            // return builder.create();
+            default:
+                // do dialog will be created
+                return null;
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        // save the current directory
+        Editor editor = getSharedPreferences(PREFERENCES_FILE, MODE_PRIVATE).edit();
+        editor.clear();
+        if (this.currentDirectory != null) {
+            editor.putString(CURRENT_DIRECTORY, this.currentDirectory.getAbsolutePath());
+        }
+        editor.commit();
+    }
+
+    @TargetApi(11)
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+            getActionBar().hide();
+
+        // check if the full screen mode should be activated
+        // if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
+        // false)) {
+        // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        // } else {
+        // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        // }
+
+        // restore the current directory
+        SharedPreferences preferences = getSharedPreferences(PREFERENCES_FILE,
+                MODE_PRIVATE);
+        this.currentDirectory = new File(preferences.getString(CURRENT_DIRECTORY,
+                DEFAULT_DIRECTORY));
+        if (!this.currentDirectory.exists() || !this.currentDirectory.canRead()) {
+            this.currentDirectory = new File(DEFAULT_DIRECTORY);
+        }
+        browseToCurrentDirectory();
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/filepicker/FilePickerIconAdapter.java b/vtm-app/src/org/oscim/app/filepicker/FilePickerIconAdapter.java
new file mode 100755
index 00000000..5ece834e
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/filepicker/FilePickerIconAdapter.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.filepicker;
+
+import android.content.Context;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import org.oscim.app.R;
+
+import java.io.File;
+
+/**
+ * An adapter for the FilePicker GridView.
+ */
+class FilePickerIconAdapter extends BaseAdapter {
+    private final Context context;
+    private File currentFile;
+    private File[] files;
+    private boolean hasParentFolder;
+    private TextView textView;
+
+    /**
+     * Creates a new FilePickerIconAdapter with the given context.
+     *
+     * @param context the context of this adapter, through which new Views are
+     *                created.
+     */
+    FilePickerIconAdapter(Context context) {
+        super();
+        this.context = context;
+    }
+
+    @Override
+    public int getCount() {
+        if (this.files == null) {
+            return 0;
+        }
+        return this.files.length;
+    }
+
+    @Override
+    public Object getItem(int index) {
+        return this.files[index];
+    }
+
+    @Override
+    public long getItemId(int index) {
+        return index;
+    }
+
+    @Override
+    public View getView(int index, View convertView, ViewGroup parent) {
+        if (convertView instanceof TextView) {
+            // recycle the old view
+            this.textView = (TextView) convertView;
+        } else {
+            // create a new view object
+            this.textView = new TextView(this.context);
+            this.textView.setLines(2);
+            this.textView.setGravity(Gravity.CENTER_HORIZONTAL);
+            this.textView.setPadding(5, 10, 5, 10);
+        }
+
+        if (index == 0 && this.hasParentFolder) {
+            // the parent directory of the current folder
+            this.textView.setCompoundDrawablesWithIntrinsicBounds(0,
+                    R.drawable.file_picker_back, 0, 0);
+            this.textView.setText("..");
+        } else {
+            this.currentFile = this.files[index];
+            if (this.currentFile.isDirectory()) {
+                this.textView.setCompoundDrawablesWithIntrinsicBounds(0,
+                        R.drawable.file_picker_folder,
+                        0,
+                        0);
+            } else {
+                this.textView.setCompoundDrawablesWithIntrinsicBounds(0,
+                        R.drawable.file_picker_file,
+                        0,
+                        0);
+            }
+            this.textView.setText(this.currentFile.getName());
+        }
+        return this.textView;
+    }
+
+    /**
+     * Sets the data of this adapter.
+     *
+     * @param files              the new files for this adapter.
+     * @param newHasParentFolder true if the file array has a parent folder at index 0, false
+     *                           otherwise.
+     */
+    void setFiles(File[] files, boolean newHasParentFolder) {
+        this.files = files.clone();
+        this.hasParentFolder = newHasParentFolder;
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/location/Compass.java b/vtm-app/src/org/oscim/app/location/Compass.java
new file mode 100644
index 00000000..cdfbd8df
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/location/Compass.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2013 Ahmad Saleem
+ * Copyright 2013 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.oscim.app.location;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.view.animation.Animation;
+import android.view.animation.RotateAnimation;
+import android.widget.ImageView;
+
+import org.oscim.app.App;
+import org.oscim.app.R;
+import org.oscim.core.MapPosition;
+import org.oscim.event.Event;
+import org.oscim.layers.Layer;
+import org.oscim.map.Map;
+
+@SuppressWarnings("deprecation")
+public class Compass extends Layer implements SensorEventListener,
+        Map.UpdateListener {
+
+    // final static Logger log = LoggerFactory.getLogger(Compass.class);
+
+    public enum Mode {
+        OFF, C2D, C3D,
+    }
+
+    private final SensorManager mSensorManager;
+    private final ImageView mArrowView;
+
+    // private final float[] mRotationM = new float[9];
+    private final float[] mRotationV = new float[3];
+
+    // private float[] mAccelV = new float[3];
+    // private float[] mMagnetV = new float[3];
+    // private boolean mLastAccelerometerSet;
+    // private boolean mLastMagnetometerSet;
+
+    private float mCurRotation;
+    private float mCurTilt;
+
+    private boolean mControlOrientation;
+
+    private Mode mMode = Mode.OFF;
+    private int mListeners;
+
+    @Override
+    public void onMapEvent(Event e, MapPosition mapPosition) {
+        if (!mControlOrientation) {
+            float rotation = -mapPosition.bearing;
+            adjustArrow(rotation, rotation);
+        }
+    }
+
+    public Compass(Context context, Map map) {
+        super(map);
+
+        mSensorManager = (SensorManager) context
+                .getSystemService(Context.SENSOR_SERVICE);
+
+        // List<Sensor> s = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+        // for (Sensor sensor : s)
+        // log.debug(sensor.toString());
+
+        mArrowView = (ImageView) App.activity.findViewById(R.id.compass);
+
+        setEnabled(false);
+    }
+
+    public synchronized float getRotation() {
+        return mCurRotation;
+    }
+
+    public void controlView(boolean enable) {
+        mControlOrientation = enable;
+    }
+
+    public boolean controlView() {
+        return mControlOrientation;
+    }
+
+    public void setMode(Mode mode) {
+        if (mode == mMode)
+            return;
+
+        if (mode == Mode.OFF) {
+            setEnabled(false);
+
+            mMap.getEventLayer().enableRotation(true);
+            mMap.getEventLayer().enableTilt(true);
+        } else if (mMode == Mode.OFF) {
+            setEnabled(true);
+        }
+
+        if (mode == Mode.C3D) {
+            mMap.getEventLayer().enableRotation(false);
+            mMap.getEventLayer().enableTilt(false);
+        } else if (mode == Mode.C2D) {
+            mMap.getEventLayer().enableRotation(false);
+            mMap.getEventLayer().enableTilt(true);
+        }
+
+        mMode = mode;
+    }
+
+    public Mode getMode() {
+        return mMode;
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        mListeners += enabled ? 1 : -1;
+
+        if (mListeners == 1) {
+            resume();
+        } else if (mListeners == 0) {
+            pause();
+
+        } else if (mListeners < 0) {
+            // then bad
+            mListeners = 0;
+        }
+    }
+
+    public void resume() {
+        if (mListeners <= 0)
+            return;
+
+        super.setEnabled(true);
+
+        Sensor sensor;
+        // Sensor sensor =
+        // mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
+        // Sensor sensor =
+        // mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+        // sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
+        // mSensorManager.registerListener(this, sensor,
+        // SensorManager.SENSOR_DELAY_UI);
+        // sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
+        // mSensorManager.registerListener(this, sensor,
+        // SensorManager.SENSOR_DELAY_UI);
+
+        sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
+        mSensorManager.registerListener(this, sensor,
+                SensorManager.SENSOR_DELAY_UI);
+
+        // mLastAccelerometerSet = false;
+        // mLastMagnetometerSet = false;
+    }
+
+    public void pause() {
+        if (mListeners <= 0)
+            return;
+
+        super.setEnabled(false);
+        mSensorManager.unregisterListener(this);
+    }
+
+    public void adjustArrow(float prev, float cur) {
+        Animation an = new RotateAnimation(-prev,
+                -cur,
+                Animation.RELATIVE_TO_SELF,
+                0.5f,
+                Animation.RELATIVE_TO_SELF,
+                0.5f);
+
+        an.setDuration(100);
+        an.setRepeatCount(0);
+        an.setFillAfter(true);
+
+        mArrowView.startAnimation(an);
+    }
+
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+
+        if (event.sensor.getType() != Sensor.TYPE_ORIENTATION)
+            return;
+        System.arraycopy(event.values, 0, mRotationV, 0, event.values.length);
+
+        // SensorManager.getRotationMatrixFromVector(mRotationM, event.values);
+        // SensorManager.getOrientation(mRotationM, mRotationV);
+
+        // int type = event.sensor.getType();
+        // if (type == Sensor.TYPE_ACCELEROMETER) {
+        // System.arraycopy(event.values, 0, mAccelV, 0, event.values.length);
+        // mLastAccelerometerSet = true;
+        // } else if (type == Sensor.TYPE_MAGNETIC_FIELD) {
+        // System.arraycopy(event.values, 0, mMagnetV, 0, event.values.length);
+        // mLastMagnetometerSet = true;
+        // } else {
+        // return;
+        // }
+        // if (!mLastAccelerometerSet || !mLastMagnetometerSet)
+        // return;
+
+        // SensorManager.getRotationMatrix(mRotationM, null, mAccelV, mMagnetV);
+        // SensorManager.getOrientation(mRotationM, mRotationV);
+
+        // float rotation = (float) Math.toDegrees(mRotationV[0]);
+        float rotation = mRotationV[0];
+
+        // handle(event);
+        // if (!mOrientationOK)
+        // return;
+        // float rotation = (float) Math.toDegrees(mAzimuthRadians);
+
+        float change = rotation - mCurRotation;
+        if (change > 180)
+            change -= 360;
+        else if (change < -180)
+            change += 360;
+
+        // low-pass
+        change *= 0.05;
+
+        rotation = mCurRotation + change;
+
+        if (rotation > 180)
+            rotation -= 360;
+        else if (rotation < -180)
+            rotation += 360;
+
+        // float tilt = (float) Math.toDegrees(mRotationV[1]);
+        // float tilt = (float) Math.toDegrees(mPitchAxisRadians);
+        float tilt = mRotationV[1];
+
+        mCurTilt = mCurTilt + 0.2f * (tilt - mCurTilt);
+
+        if (mMode != Mode.OFF) {
+            boolean redraw = false;
+
+            if (Math.abs(change) > 0.01) {
+                adjustArrow(mCurRotation, rotation);
+                mMap.viewport().setRotation(-rotation);
+                redraw = true;
+            }
+
+            if (mMode == Mode.C3D)
+                redraw |= mMap.viewport().setTilt(-mCurTilt * 1.5f);
+
+            if (redraw)
+                mMap.updateMap(true);
+        }
+        mCurRotation = rotation;
+    }
+
+    // from http://stackoverflow.com/questions/16317599/android-compass-that-
+    // can-compensate-for-tilt-and-pitch/16386066#16386066
+
+    // private int mGravityAccuracy;
+    // private int mMagneticFieldAccuracy;
+
+    // private float[] mGravityV = new float[3];
+    // private float[] mMagFieldV = new float[3];
+    // private float[] mEastV = new float[3];
+    // private float[] mNorthV = new float[3];
+    //
+    // private float mNormGravity;
+    // private float mNormMagField;
+    //
+    // private boolean mOrientationOK;
+    // private float mAzimuthRadians;
+    // private float mPitchRadians;
+    // private float mPitchAxisRadians;
+    //
+    // private void handle(SensorEvent event) {
+    // int SensorType = event.sensor.getType();
+    // switch (SensorType) {
+    // case Sensor.TYPE_GRAVITY:
+    // mLastAccelerometerSet = true;
+    // System.arraycopy(event.values, 0, mGravityV, 0, mGravityV.length);
+    // mNormGravity = (float) Math.sqrt(mGravityV[0] * mGravityV[0]
+    // + mGravityV[1] * mGravityV[1] + mGravityV[2]
+    // * mGravityV[2]);
+    // for (int i = 0; i < mGravityV.length; i++)
+    // mGravityV[i] /= mNormGravity;
+    // break;
+    // case Sensor.TYPE_MAGNETIC_FIELD:
+    // mLastMagnetometerSet = true;
+    // System.arraycopy(event.values, 0, mMagFieldV, 0, mMagFieldV.length);
+    // mNormMagField = (float) Math.sqrt(mMagFieldV[0] * mMagFieldV[0]
+    // + mMagFieldV[1] * mMagFieldV[1] + mMagFieldV[2]
+    // * mMagFieldV[2]);
+    // for (int i = 0; i < mMagFieldV.length; i++)
+    // mMagFieldV[i] /= mNormMagField;
+    // break;
+    // }
+    // if (!mLastAccelerometerSet || !mLastMagnetometerSet)
+    // return;
+    //
+    // // first calculate the horizontal vector that points due east
+    // float ex = mMagFieldV[1] * mGravityV[2] - mMagFieldV[2] * mGravityV[1];
+    // float ey = mMagFieldV[2] * mGravityV[0] - mMagFieldV[0] * mGravityV[2];
+    // float ez = mMagFieldV[0] * mGravityV[1] - mMagFieldV[1] * mGravityV[0];
+    // float normEast = (float) Math.sqrt(ex * ex + ey * ey + ez * ez);
+    //
+    // if (mNormGravity * mNormMagField * normEast < 0.1f) { // Typical values
+    // are > 100.
+    // // device is close to free fall (or in space?), or close to magnetic
+    // north pole.
+    // mOrientationOK = false;
+    // return;
+    // }
+    //
+    // mEastV[0] = ex / normEast;
+    // mEastV[1] = ey / normEast;
+    // mEastV[2] = ez / normEast;
+    //
+    // // next calculate the horizontal vector that points due north
+    // float mdotG = (mGravityV[0] * mMagFieldV[0]
+    // + mGravityV[1] * mMagFieldV[1]
+    // + mGravityV[2] * mMagFieldV[2]);
+    //
+    // float nx = mMagFieldV[0] - mGravityV[0] * mdotG;
+    // float ny = mMagFieldV[1] - mGravityV[1] * mdotG;
+    // float nz = mMagFieldV[2] - mGravityV[2] * mdotG;
+    // float normNorth = (float) Math.sqrt(nx * nx + ny * ny + nz * nz);
+    //
+    // mNorthV[0] = nx / normNorth;
+    // mNorthV[1] = ny / normNorth;
+    // mNorthV[2] = nz / normNorth;
+    //
+    // // take account of screen rotation away from its natural rotation
+    // //int rotation =
+    // App.activity.getWindowManager().getDefaultDisplay().getRotation();
+    // float screenDirection = 0;
+    // //switch(rotation) {
+    // // case Surface.ROTATION_0: screenDirection = 0; break;
+    // // case Surface.ROTATION_90: screenDirection = (float)Math.PI/2; break;
+    // // case Surface.ROTATION_180: screenDirection = (float)Math.PI; break;
+    // // case Surface.ROTATION_270: screenDirection = 3*(float)Math.PI/2;
+    // break;
+    // //}
+    // // NB: the rotation matrix has now effectively been calculated. It
+    // consists of
+    // // the three vectors mEastV[], mNorthV[] and mGravityV[]
+    //
+    // // calculate all the required angles from the rotation matrix
+    // // NB: see
+    // http://math.stackexchange.com/questions/381649/whats-the-best-3d-angular-
+    // // co-ordinate-system-for-working-with-smartfone-apps
+    // float sin = mEastV[1] - mNorthV[0], cos = mEastV[0] + mNorthV[1];
+    // mAzimuthRadians = (float) (sin != 0 && cos != 0 ? Math.atan2(sin, cos) :
+    // 0);
+    // mPitchRadians = (float) Math.acos(mGravityV[2]);
+    //
+    // sin = -mEastV[1] - mNorthV[0];
+    // cos = mEastV[0] - mNorthV[1];
+    //
+    // float aximuthPlusTwoPitchAxisRadians =
+    // (float) (sin != 0 && cos != 0 ? Math.atan2(sin, cos) : 0);
+    //
+    // mPitchAxisRadians = (float) (aximuthPlusTwoPitchAxisRadians -
+    // mAzimuthRadians) / 2;
+    // mAzimuthRadians += screenDirection;
+    // mPitchAxisRadians += screenDirection;
+    //
+    // mOrientationOK = true;
+    // }
+
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        // int type = sensor.getType();
+        // switch (type) {
+        // case Sensor.TYPE_GRAVITY:
+        // mGravityAccuracy = accuracy;
+        // break;
+        // case Sensor.TYPE_MAGNETIC_FIELD:
+        // mMagneticFieldAccuracy = accuracy;
+        // break;
+        // }
+    }
+
+}
diff --git a/vtm-app/src/org/oscim/app/location/LocationDialog.java b/vtm-app/src/org/oscim/app/location/LocationDialog.java
new file mode 100644
index 00000000..d37fb133
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/location/LocationDialog.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2012 Hannes Janetzek
+ * Copyright 2016 devemux86
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.location;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import org.oscim.app.App;
+import org.oscim.app.R;
+import org.oscim.app.TileMap;
+import org.oscim.core.MapPosition;
+import org.oscim.map.Map;
+
+public class LocationDialog {
+
+    public void prepareDialog(Map map, final Dialog dialog) {
+        EditText editText = (EditText) dialog.findViewById(R.id.latitude);
+
+        MapPosition mapCenter = map.getMapPosition();
+
+        editText.setText(Double.toString(mapCenter.getLatitude()));
+
+        editText = (EditText) dialog.findViewById(R.id.longitude);
+        editText.setText(Double.toString(mapCenter.getLongitude()));
+
+        SeekBar zoomlevel = (SeekBar) dialog.findViewById(R.id.zoomLevel);
+        zoomlevel.setMax(20);
+        zoomlevel.setProgress(10);
+
+        final TextView textView = (TextView) dialog.findViewById(R.id.zoomlevelValue);
+        textView.setText(String.valueOf(zoomlevel.getProgress()));
+        zoomlevel.setOnSeekBarChangeListener(new SeekBarChangeListener(textView));
+    }
+
+    public Dialog createDialog(final TileMap map) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(map);
+        builder.setIcon(android.R.drawable.ic_menu_mylocation);
+        builder.setTitle(R.string.menu_position_enter_coordinates);
+        LayoutInflater factory = LayoutInflater.from(map);
+        final View view = factory.inflate(R.layout.dialog_enter_coordinates, null);
+        builder.setView(view);
+
+        builder.setPositiveButton(R.string.go_to_position,
+                new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        // disable GPS follow mode if it is enabled
+                        //map.mLocation.disableSnapToLocation();
+                        if (map.getLocationHandler().getMode() == LocationHandler.Mode.SNAP)
+                            map.getLocationHandler()
+                                    .setMode(LocationHandler.Mode.SHOW);
+
+                        // set the map center and zoom level
+                        EditText latitudeView = (EditText) view
+                                .findViewById(R.id.latitude);
+                        EditText longitudeView = (EditText) view
+                                .findViewById(R.id.longitude);
+                        double latitude = Double.parseDouble(latitudeView.getText()
+                                .toString());
+                        double longitude = Double.parseDouble(longitudeView.getText()
+                                .toString());
+
+                        SeekBar zoomLevelView = (SeekBar) view
+                                .findViewById(R.id.zoomLevel);
+
+                        int zoom = zoomLevelView.getProgress();
+
+                        MapPosition mapPosition = new MapPosition();
+                        mapPosition.setPosition(latitude, longitude);
+                        mapPosition.setZoomLevel(zoom);
+                        App.map.setMapPosition(mapPosition);
+                    }
+                });
+        builder.setNegativeButton(R.string.cancel, null);
+        return builder.create();
+    }
+
+    class SeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {
+        private final TextView textView;
+
+        SeekBarChangeListener(TextView textView) {
+            this.textView = textView;
+        }
+
+        @Override
+        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+            this.textView.setText(String.valueOf(progress));
+        }
+
+        @Override
+        public void onStartTrackingTouch(SeekBar seekBar) {
+            // do nothing
+        }
+
+        @Override
+        public void onStopTrackingTouch(SeekBar seekBar) {
+            // do nothing
+        }
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/location/LocationHandler.java b/vtm-app/src/org/oscim/app/location/LocationHandler.java
new file mode 100644
index 00000000..723e4f77
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/location/LocationHandler.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2013 Hannes Janetzek
+ * Copyright 2013 Ahmad Al-saleem
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.location;
+
+import android.content.Context;
+import android.location.Criteria;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+
+import org.oscim.app.App;
+import org.oscim.app.R;
+import org.oscim.app.TileMap;
+import org.oscim.core.MapPosition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LocationHandler implements LocationListener {
+    final static Logger log = LoggerFactory.getLogger(LocationHandler.class);
+
+    public enum Mode {
+        OFF,
+        SHOW,
+        SNAP,
+    }
+
+    private final static int DIALOG_LOCATION_PROVIDER_DISABLED = 2;
+    private final static int SHOW_LOCATION_ZOOM = 14;
+
+    private final LocationManager mLocationManager;
+    private final LocationOverlay mLocationOverlay;
+
+    private Mode mMode = Mode.OFF;
+
+    private boolean mSetCenter;
+    private MapPosition mMapPosition;
+
+    public LocationHandler(TileMap tileMap, Compass compass) {
+        mLocationManager = (LocationManager) tileMap
+                .getSystemService(Context.LOCATION_SERVICE);
+
+        mLocationOverlay = new LocationOverlay(App.map, compass);
+
+        mMapPosition = new MapPosition();
+    }
+
+    public boolean setMode(Mode mode) {
+        if (mode == mMode)
+            return true;
+
+        if (mode == Mode.OFF) {
+            disableShowMyLocation();
+
+            if (mMode == Mode.SNAP)
+                App.map.getEventLayer().enableMove(true);
+        }
+
+        if (mMode == Mode.OFF) {
+            if (!enableShowMyLocation())
+                return false;
+        }
+
+        if (mode == Mode.SNAP) {
+            App.map.getEventLayer().enableMove(false);
+            gotoLastKnownPosition();
+        } else {
+            App.map.getEventLayer().enableMove(true);
+        }
+
+        // FIXME?
+        mSetCenter = false;
+        mMode = mode;
+
+        return true;
+    }
+
+    public Mode getMode() {
+        return mMode;
+    }
+
+    public boolean isFirstCenter() {
+        return mSetCenter;
+    }
+
+    @SuppressWarnings("deprecation")
+    private boolean enableShowMyLocation() {
+
+        Criteria criteria = new Criteria();
+        criteria.setAccuracy(Criteria.ACCURACY_FINE);
+        String bestProvider = mLocationManager.getBestProvider(criteria, true);
+
+        if (bestProvider == null) {
+            App.activity.showDialog(DIALOG_LOCATION_PROVIDER_DISABLED);
+            return false;
+        }
+
+        mLocationManager.requestLocationUpdates(bestProvider, 10000, 10, this);
+
+        Location location = gotoLastKnownPosition();
+        if (location == null)
+            return false;
+
+        mLocationOverlay.setEnabled(true);
+        mLocationOverlay.setPosition(location.getLatitude(),
+                location.getLongitude(),
+                location.getAccuracy());
+
+        // FIXME -> implement LayerGroup
+        App.map.layers().add(4, mLocationOverlay);
+
+        App.map.updateMap(true);
+        return true;
+    }
+
+    /**
+     * Disable "show my location" mode.
+     */
+    private boolean disableShowMyLocation() {
+
+        mLocationManager.removeUpdates(this);
+        mLocationOverlay.setEnabled(false);
+
+        App.map.layers().remove(mLocationOverlay);
+        App.map.updateMap(true);
+
+        return true;
+    }
+
+    public Location gotoLastKnownPosition() {
+        Location location = null;
+        float bestAccuracy = Float.MAX_VALUE;
+
+        for (String provider : mLocationManager.getProviders(true)) {
+            Location l = mLocationManager.getLastKnownLocation(provider);
+            if (l == null)
+                continue;
+
+            float accuracy = l.getAccuracy();
+            if (accuracy <= 0)
+                accuracy = Float.MAX_VALUE;
+
+            if (location == null || accuracy <= bestAccuracy) {
+                location = l;
+                bestAccuracy = accuracy;
+            }
+        }
+
+        if (location == null) {
+            App.activity.showToastOnUiThread(App.activity
+                    .getString(R.string.error_last_location_unknown));
+            return null;
+        }
+
+        App.map.getMapPosition(mMapPosition);
+
+        if (mMapPosition.zoomLevel < SHOW_LOCATION_ZOOM)
+            mMapPosition.setZoomLevel(SHOW_LOCATION_ZOOM);
+
+        mMapPosition.setPosition(location.getLatitude(), location.getLongitude());
+        App.map.setMapPosition(mMapPosition);
+
+        return location;
+    }
+
+    /***
+     * LocationListener
+     ***/
+    @Override
+    public void onLocationChanged(Location location) {
+
+        if (mMode == Mode.OFF)
+            return;
+
+        double lat = location.getLatitude();
+        double lon = location.getLongitude();
+
+        log.debug("update location " + lat + ":" + lon);
+
+        if (mSetCenter || mMode == Mode.SNAP) {
+            mSetCenter = false;
+
+            App.map.getMapPosition(mMapPosition);
+            mMapPosition.setPosition(lat, lon);
+            App.map.setMapPosition(mMapPosition);
+        }
+
+        mLocationOverlay.setPosition(lat, lon, location.getAccuracy());
+    }
+
+    @Override
+    public void onProviderDisabled(String provider) {
+    }
+
+    @Override
+    public void onProviderEnabled(String provider) {
+    }
+
+    @Override
+    public void onStatusChanged(String provider, int status, Bundle extras) {
+    }
+
+    public void setCenterOnFirstFix() {
+        mSetCenter = true;
+    }
+
+    public void pause() {
+        if (mMode != Mode.OFF) {
+            log.debug("pause location listener");
+        }
+    }
+
+    public void resume() {
+        if (mMode != Mode.OFF) {
+            Criteria criteria = new Criteria();
+            criteria.setAccuracy(Criteria.ACCURACY_FINE);
+            String bestProvider = mLocationManager.getBestProvider(criteria, true);
+            mLocationManager.requestLocationUpdates(bestProvider, 10000, 10, this);
+        }
+    }
+
+}
diff --git a/vtm-app/src/org/oscim/app/location/LocationOverlay.java b/vtm-app/src/org/oscim/app/location/LocationOverlay.java
new file mode 100644
index 00000000..c3a4dd2d
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/location/LocationOverlay.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2013 Ahmad Saleem
+ * Copyright 2013 Hannes Janetzek
+ * Copyright 2016 devemux86
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.location;
+
+import android.os.SystemClock;
+
+import org.oscim.backend.GL;
+import org.oscim.core.Box;
+import org.oscim.core.MercatorProjection;
+import org.oscim.core.Point;
+import org.oscim.core.Tile;
+import org.oscim.layers.Layer;
+import org.oscim.map.Map;
+import org.oscim.renderer.GLShader;
+import org.oscim.renderer.GLState;
+import org.oscim.renderer.GLViewport;
+import org.oscim.renderer.LayerRenderer;
+import org.oscim.renderer.MapRenderer;
+import org.oscim.utils.FastMath;
+import org.oscim.utils.math.Interpolation;
+
+import static org.oscim.backend.GLAdapter.gl;
+
+public class LocationOverlay extends Layer {
+    private final int SHOW_ACCURACY_ZOOM = 16;
+
+    private final Point mLocation = new Point();
+    private double mRadius;
+
+    private final Compass mCompass;
+
+    public LocationOverlay(Map map, Compass compass) {
+        super(map);
+        mRenderer = new LocationIndicator(map);
+        mCompass = compass;
+    }
+
+    public void setPosition(double latitude, double longitude, double accuracy) {
+        mLocation.x = MercatorProjection.longitudeToX(longitude);
+        mLocation.y = MercatorProjection.latitudeToY(latitude);
+        mRadius = accuracy / MercatorProjection.groundResolution(latitude, 1);
+        ((LocationIndicator) mRenderer).animate(true);
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (enabled == isEnabled())
+            return;
+
+        super.setEnabled(enabled);
+
+        if (!enabled)
+            ((LocationIndicator) mRenderer).animate(false);
+
+        mCompass.setEnabled(enabled);
+    }
+
+    public class LocationIndicator extends LayerRenderer {
+        private int mShaderProgram;
+        private int hVertexPosition;
+        private int hMatrixPosition;
+        private int hScale;
+        private int hPhase;
+        private int hDirection;
+
+        private final float CIRCLE_SIZE = 60;
+
+        private final static long ANIM_RATE = 50;
+        private final static long INTERVAL = 2000;
+
+        private final Point mIndicatorPosition = new Point();
+
+        private final Point mScreenPoint = new Point();
+        private final Box mBBox = new Box();
+
+        private boolean mInitialized;
+
+        private boolean mLocationIsVisible;
+
+        private boolean mRunAnim;
+        private long mAnimStart;
+
+        public LocationIndicator(final Map map) {
+            super();
+        }
+
+        private void animate(boolean enable) {
+            if (mRunAnim == enable)
+                return;
+
+            mRunAnim = enable;
+            if (!enable)
+                return;
+
+            final Runnable action = new Runnable() {
+                private long lastRun;
+
+                @Override
+                public void run() {
+                    if (!mRunAnim)
+                        return;
+
+                    long diff = SystemClock.elapsedRealtime() - lastRun;
+                    mMap.postDelayed(this, Math.min(ANIM_RATE, diff));
+                    mMap.render();
+                }
+            };
+
+            mAnimStart = SystemClock.elapsedRealtime();
+            mMap.postDelayed(action, ANIM_RATE);
+        }
+
+        private float animPhase() {
+            return (float) ((MapRenderer.frametime - mAnimStart) % INTERVAL) / INTERVAL;
+        }
+
+        @Override
+        public void update(GLViewport v) {
+
+            if (!mInitialized) {
+                init();
+                mInitialized = true;
+            }
+
+            if (!isEnabled()) {
+                setReady(false);
+                return;
+            }
+
+            if (!v.changed() && isReady())
+                return;
+
+            setReady(true);
+
+            int width = mMap.getWidth();
+            int height = mMap.getHeight();
+
+            // clamp location to a position that can be
+            // savely translated to screen coordinates
+            v.getBBox(mBBox, 0);
+
+            double x = mLocation.x;
+            double y = mLocation.y;
+
+            if (!mBBox.contains(mLocation)) {
+                x = FastMath.clamp(x, mBBox.xmin, mBBox.xmax);
+                y = FastMath.clamp(y, mBBox.ymin, mBBox.ymax);
+            }
+
+            // get position of Location in pixel relative to
+            // screen center
+            v.toScreenPoint(x, y, mScreenPoint);
+
+            x = mScreenPoint.x + width / 2;
+            y = mScreenPoint.y + height / 2;
+
+            // clip position to screen boundaries
+            int visible = 0;
+
+            if (x > width - 5)
+                x = width;
+            else if (x < 5)
+                x = 0;
+            else
+                visible++;
+
+            if (y > height - 5)
+                y = height;
+            else if (y < 5)
+                y = 0;
+            else
+                visible++;
+
+            mLocationIsVisible = (visible == 2);
+
+            // set location indicator position
+            v.fromScreenPoint(x, y, mIndicatorPosition);
+        }
+
+        @Override
+        public void render(GLViewport v) {
+
+            GLState.useProgram(mShaderProgram);
+            GLState.blend(true);
+            GLState.test(false, false);
+
+            GLState.enableVertexArrays(hVertexPosition, -1);
+            MapRenderer.bindQuadVertexVBO(hVertexPosition/*, true*/);
+
+            float radius = CIRCLE_SIZE;
+
+            animate(true);
+            boolean viewShed = false;
+            if (!mLocationIsVisible /* || pos.zoomLevel < SHOW_ACCURACY_ZOOM */) {
+                //animate(true);
+            } else {
+                if (v.pos.zoomLevel >= SHOW_ACCURACY_ZOOM)
+                    radius = (float) (mRadius * v.pos.scale);
+
+                viewShed = true;
+                //animate(false);
+            }
+            gl.uniform1f(hScale, radius);
+
+            double x = mIndicatorPosition.x - v.pos.x;
+            double y = mIndicatorPosition.y - v.pos.y;
+            double tileScale = Tile.SIZE * v.pos.scale;
+
+            v.mvp.setTransScale((float) (x * tileScale), (float) (y * tileScale), 1);
+            v.mvp.multiplyMM(v.viewproj, v.mvp);
+            v.mvp.setAsUniform(hMatrixPosition);
+
+            if (!viewShed) {
+                float phase = Math.abs(animPhase() - 0.5f) * 2;
+                //phase = Interpolation.fade.apply(phase);
+                phase = Interpolation.swing.apply(phase);
+
+                gl.uniform1f(hPhase, 0.8f + phase * 0.2f);
+            } else {
+                gl.uniform1f(hPhase, 1);
+            }
+
+            if (viewShed && mLocationIsVisible) {
+                float rotation = mCompass.getRotation() - 90;
+                gl.uniform2f(hDirection,
+                        (float) Math.cos(Math.toRadians(rotation)),
+                        (float) Math.sin(Math.toRadians(rotation)));
+            } else {
+                gl.uniform2f(hDirection, 0, 0);
+            }
+
+            gl.drawArrays(GL.TRIANGLE_STRIP, 0, 4);
+        }
+
+        private boolean init() {
+            int shader = GLShader.createProgram(vShaderStr, fShaderStr);
+            if (shader == 0)
+                return false;
+
+            mShaderProgram = shader;
+            hVertexPosition = gl.getAttribLocation(shader, "a_pos");
+            hMatrixPosition = gl.getUniformLocation(shader, "u_mvp");
+            hPhase = gl.getUniformLocation(shader, "u_phase");
+            hScale = gl.getUniformLocation(shader, "u_scale");
+            hDirection = gl.getUniformLocation(shader, "u_dir");
+
+            return true;
+        }
+
+        private final static String vShaderStr = ""
+                + "precision mediump float;"
+                + "uniform mat4 u_mvp;"
+                + "uniform float u_phase;"
+                + "uniform float u_scale;"
+                + "attribute vec2 a_pos;"
+                + "varying vec2 v_tex;"
+                + "void main() {"
+                + "  gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0);"
+                + "  v_tex = a_pos;"
+                + "}";
+
+        private final static String fShaderStr = ""
+                + "precision mediump float;"
+                + "varying vec2 v_tex;"
+                + "uniform float u_scale;"
+                + "uniform float u_phase;"
+                + "uniform vec2 u_dir;"
+
+                + "void main() {"
+                + "  float len = 1.0 - length(v_tex);"
+                + "  if (u_dir.x == 0.0 && u_dir.y == 0.0){"
+                + "  gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * len;"
+                + "  } else {"
+                ///  outer ring
+                + "  float a = smoothstep(0.0, 2.0 / u_scale, len);"
+                ///  inner ring
+                + "  float b = 0.5 * smoothstep(4.0 / u_scale, 5.0 / u_scale, len);"
+                ///  center point
+                + "  float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));"
+                + "  vec2 dir = normalize(v_tex);"
+                + "  float d = 1.0 - dot(dir, u_dir); "
+                ///  0.5 width of viewshed
+                + "  d = clamp(step(0.5, d), 0.4, 0.7);"
+                ///  - subtract inner from outer to create the outline
+                ///  - multiply by viewshed
+                ///  - add center point
+                + "  a = d * (a - (b + c)) + c;"
+                + "  gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;"
+                + "}}";
+
+        //private final static String fShaderStr = ""
+        //        + "precision mediump float;"
+        //        + "varying vec2 v_tex;"
+        //        + "uniform float u_scale;"
+        //        + "uniform float u_phase;"
+        //        + "uniform vec2 u_dir;"
+        //        + "void main() {"
+        //        + "  float len = 1.0 - length(v_tex);"
+        //        ///  outer ring
+        //        + "  float a = smoothstep(0.0, 2.0 / u_scale, len);"
+        //        ///  inner ring
+        //        + "  float b = 0.8 * smoothstep(3.0 / u_scale, 4.0 / u_scale, len);"
+        //        ///  center point
+        //        + "  float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));"
+        //        + "  vec2 dir = normalize(v_tex);"
+        //        + "  float d = dot(dir, u_dir); "
+        //        ///  0.5 width of viewshed
+        //        + "  d = clamp(smoothstep(0.7, 0.7 + 2.0/u_scale, d) * len, 0.0, 1.0);"
+        //        ///  - subtract inner from outer to create the outline
+        //        ///  - multiply by viewshed
+        //        ///  - add center point
+        //        + "  a = max(d, (a - (b + c)) + c);"
+        //        + "  gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;"
+        //        + "}";
+
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/preferences/CacheSizePreference.java b/vtm-app/src/org/oscim/app/preferences/CacheSizePreference.java
new file mode 100644
index 00000000..02d82531
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/preferences/CacheSizePreference.java
@@ -0,0 +1,219 @@
+package org.oscim.app.preferences;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.RelativeLayout;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+
+import org.oscim.app.R;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CacheSizePreference extends Preference implements OnSeekBarChangeListener {
+    final static Logger log = LoggerFactory.getLogger(CacheSizePreference.class);
+
+    private static final String NS_OCIM_APP = "http://app.oscim.org";
+    private static final int DEFAULT_VALUE = 50;
+
+    private int mMaxValue = 50;
+    private int mMinValue = 0;
+    private int mInterval = 1;
+    private int mCurrentValue;
+    private String mUnitsLeft = "";
+    private String mUnitsRight = "";
+    private SeekBar mSeekBar;
+
+    private TextView mStatusText;
+
+    public CacheSizePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initPreference(context, attrs);
+    }
+
+    public CacheSizePreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        initPreference(context, attrs);
+    }
+
+    private void initPreference(Context context, AttributeSet attrs) {
+        setValuesFromXml(attrs);
+        mSeekBar = new SeekBar(context, attrs);
+        mSeekBar.setMax(mMaxValue - mMinValue);
+        mSeekBar.setOnSeekBarChangeListener(this);
+    }
+
+    private void setValuesFromXml(AttributeSet attrs) {
+        //StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
+        //double sdAvailSize = (double) stat.getAvailableBlocks()
+        //        * (double) stat.getBlockSize();
+        //One binary megabyte equals 1,048,576 bytes.
+        // otherwise we need an logarithmic scale to set a sane value with the slider...
+        int megaAvailable = 50; //(int)sdAvailSize / 1048576;
+
+        mMaxValue = megaAvailable;//attrs.getAttributeIntValue(ANDROIDNS, "max", 100);
+        mMinValue = attrs.getAttributeIntValue(NS_OCIM_APP, "min", 0);
+
+        mUnitsLeft = getAttributeStringValue(attrs, NS_OCIM_APP, "unitsLeft", "");
+        //String units = getAttributeStringValue(attrs, NS_OCIM_APP, "units", "");
+        mUnitsRight = "/" + String.valueOf(megaAvailable) + "MB";
+        try {
+            String newInterval = attrs.getAttributeValue(NS_OCIM_APP, "interval");
+            if (newInterval != null)
+                mInterval = Integer.parseInt(newInterval);
+        } catch (Exception e) {
+            log.error("", e);
+        }
+
+    }
+
+    private String getAttributeStringValue(AttributeSet attrs, String namespace, String name,
+                                           String defaultValue) {
+        String value = attrs.getAttributeValue(namespace, name);
+        if (value == null)
+            value = defaultValue;
+
+        return value;
+    }
+
+    @Override
+    protected View onCreateView(ViewGroup parent) {
+
+        RelativeLayout layout = null;
+
+        try {
+            LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+
+            layout = (RelativeLayout) mInflater
+                    .inflate(R.layout.seek_bar_preference, parent, false);
+        } catch (Exception e) {
+            log.error("", e);
+        }
+
+        return layout;
+
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void onBindView(View view) {
+        super.onBindView(view);
+
+        try {
+            // move our seekbar to the new view we've been given
+            ViewParent oldContainer = mSeekBar.getParent();
+            ViewGroup newContainer = (ViewGroup) view.findViewById(R.id.seekBarPrefBarContainer);
+
+            if (oldContainer != newContainer) {
+                // remove the seekbar from the old view
+                if (oldContainer != null) {
+                    ((ViewGroup) oldContainer).removeView(mSeekBar);
+                }
+                // remove the existing seekbar (there may not be one) and add ours
+                newContainer.removeAllViews();
+                newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT,
+                        ViewGroup.LayoutParams.WRAP_CONTENT);
+            }
+        } catch (Exception ex) {
+            log.error("Error binding view: " + ex.toString());
+        }
+
+        updateView(view);
+    }
+
+    /**
+     * Update a SeekBarPreference view with our current state
+     *
+     * @param view
+     */
+    protected void updateView(View view) {
+
+        try {
+            RelativeLayout layout = (RelativeLayout) view;
+
+            mStatusText = (TextView) layout.findViewById(R.id.seekBarPrefValue);
+            mStatusText.setText(String.valueOf(mCurrentValue));
+            mStatusText.setMinimumWidth(30);
+
+            mSeekBar.setProgress(mCurrentValue - mMinValue);
+
+            TextView unitsRight = (TextView) layout.findViewById(R.id.seekBarPrefUnitsRight);
+            unitsRight.setText(mUnitsRight);
+
+            TextView unitsLeft = (TextView) layout.findViewById(R.id.seekBarPrefUnitsLeft);
+            unitsLeft.setText(mUnitsLeft);
+
+        } catch (Exception e) {
+            log.error("", e);
+        }
+
+    }
+
+    @Override
+    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+        int newValue = progress + mMinValue;
+
+        if (newValue > mMaxValue)
+            newValue = mMaxValue;
+        else if (newValue < mMinValue)
+            newValue = mMinValue;
+        else if (mInterval != 1 && newValue % mInterval != 0)
+            newValue = Math.round(((float) newValue) / mInterval) * mInterval;
+
+        // change rejected, revert to the previous value
+        if (!callChangeListener(newValue)) {
+            seekBar.setProgress(mCurrentValue - mMinValue);
+            return;
+        }
+
+        // change accepted, store it
+        mCurrentValue = newValue;
+        mStatusText.setText(String.valueOf(newValue));
+        persistInt(newValue);
+    }
+
+    @Override
+    public void onStartTrackingTouch(SeekBar seekBar) {
+    }
+
+    @Override
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        notifyChanged();
+    }
+
+    @Override
+    protected Object onGetDefaultValue(TypedArray ta, int index) {
+
+        int defaultValue = ta.getInt(index, DEFAULT_VALUE);
+        return defaultValue;
+
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+
+        if (restoreValue) {
+            mCurrentValue = getPersistedInt(mCurrentValue);
+        } else {
+            int temp = 0;
+            try {
+                temp = (Integer) defaultValue;
+            } catch (Exception ex) {
+                log.error("Invalid default value: " + defaultValue.toString());
+            }
+
+            persistInt(temp);
+            mCurrentValue = temp;
+        }
+
+    }
+
+}
diff --git a/vtm-app/src/org/oscim/app/preferences/EditPreferences.java b/vtm-app/src/org/oscim/app/preferences/EditPreferences.java
new file mode 100644
index 00000000..cf5112d3
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/preferences/EditPreferences.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.preferences;
+
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+
+import org.oscim.app.App;
+import org.oscim.app.R;
+
+/**
+ * Activity to edit the application preferences.
+ */
+public class EditPreferences extends PreferenceActivity {
+    @SuppressWarnings("deprecation")
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.preferences);
+
+        Preference button = (Preference) findPreference("clear_cache");
+        button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference arg0) {
+                App.activity.getMapLayers().deleteCache();
+                return true;
+            }
+        });
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        overridePendingTransition(R.anim.slide_left, R.anim.slide_right2);
+    }
+
+    // @TargetApi(11)
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+        // getActionBar().hide();
+
+        // check if the full screen mode should be activated
+        // if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
+        // false)) {
+        // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        // } else {
+        // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        // }
+    }
+}
diff --git a/vtm-app/src/org/oscim/app/preferences/SeekBarPreference.java b/vtm-app/src/org/oscim/app/preferences/SeekBarPreference.java
new file mode 100644
index 00000000..5a244d29
--- /dev/null
+++ b/vtm-app/src/org/oscim/app/preferences/SeekBarPreference.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.app.preferences;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.preference.DialogPreference;
+import android.preference.PreferenceManager;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+
+/**
+ * This abstract class provides all code for a seek bar preference. Deriving
+ * classes only need to set the current and
+ * maximum value of the seek bar. An optional text message above the seek bar is
+ * also supported as well as an optional
+ * current value message below the seek bar.
+ */
+abstract class SeekBarPreference extends DialogPreference implements OnSeekBarChangeListener {
+    private TextView mCurrentValueTextView;
+    private Editor mEditor;
+    private SeekBar mPreferenceSeekBar;
+
+    /**
+     * How much the value should increase when the seek bar is moved.
+     */
+    int increment = 1;
+
+    /**
+     * The maximum value of the seek bar.
+     */
+    int max;
+
+    /**
+     * Optional text message to display on top of the seek bar.
+     */
+    String messageText;
+
+    /**
+     * The SharedPreferences instance that is used.
+     */
+    final SharedPreferences preferencesDefault;
+
+    /**
+     * The current value of the seek bar.
+     */
+    int seekBarCurrentValue;
+
+    /**
+     * Create a new seek bar preference.
+     *
+     * @param context the context of the seek bar preferences activity.
+     * @param attrs   A set of attributes (currently ignored).
+     */
+    SeekBarPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        preferencesDefault = PreferenceManager.getDefaultSharedPreferences(context);
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        // check if the "OK" button was pressed and the seek bar value has changed
+        if (which == DialogInterface.BUTTON_POSITIVE
+                && seekBarCurrentValue != mPreferenceSeekBar.getProgress()) {
+            // get the value of the seek bar and save it in the preferences
+            seekBarCurrentValue = mPreferenceSeekBar.getProgress();
+            mEditor = preferencesDefault.edit();
+            mEditor.putInt(getKey(), seekBarCurrentValue);
+            mEditor.commit();
+        }
+    }
+
+    @Override
+    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+        if (mCurrentValueTextView != null) {
+            mCurrentValueTextView.setText(getCurrentValueText(progress));
+        }
+    }
+
+    @Override
+    public void onStartTrackingTouch(SeekBar seekBar) {
+        // do nothing
+    }
+
+    @Override
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        // do nothing
+    }
+
+    @Override
+    protected View onCreateDialogView() {
+        // create a layout for the optional text messageText and the seek bar
+        LinearLayout linearLayout = new LinearLayout(getContext());
+        linearLayout.setOrientation(LinearLayout.VERTICAL);
+        linearLayout.setPadding(20, 10, 20, 10);
+
+        // check if a text message should appear above the seek bar
+        if (messageText != null) {
+            // create a text view for the text messageText
+            TextView messageTextView = new TextView(getContext());
+            messageTextView.setText(messageText);
+            messageTextView.setPadding(0, 0, 0, 20);
+            // add the text message view to the layout
+            linearLayout.addView(messageTextView);
+        }
+
+        // create the seek bar and set the maximum and current value
+        mPreferenceSeekBar = new SeekBar(getContext());
+        mPreferenceSeekBar.setOnSeekBarChangeListener(this);
+        mPreferenceSeekBar.setMax(max);
+        mPreferenceSeekBar.setProgress(Math.min(seekBarCurrentValue, max));
+        mPreferenceSeekBar.setKeyProgressIncrement(increment);
+        mPreferenceSeekBar.setPadding(0, 0, 0, 10);
+        // add the seek bar to the layout
+        linearLayout.addView(mPreferenceSeekBar);
+
+        // create the text view for the current value below the seek bar
+        mCurrentValueTextView = new TextView(getContext());
+        mCurrentValueTextView.setText(getCurrentValueText(mPreferenceSeekBar.getProgress()));
+        mCurrentValueTextView.setGravity(Gravity.CENTER_HORIZONTAL);
+        // add the current value text view to the layout
+        linearLayout.addView(mCurrentValueTextView);
+
+        return linearLayout;
+    }
+
+    /**
+     * Get the current value text.
+     *
+     * @param progress the current progress level of the seek bar.
+     * @return the new current value text
+     */
+    abstract String getCurrentValueText(int progress);
+}
diff --git a/vtm-app/src/org/oscim/overlay/DistanceTouchOverlay.java b/vtm-app/src/org/oscim/overlay/DistanceTouchOverlay.java
new file mode 100644
index 00000000..f9d57e62
--- /dev/null
+++ b/vtm-app/src/org/oscim/overlay/DistanceTouchOverlay.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2013 Ahmad Saleem
+ * Copyright 2013 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.oscim.overlay;
+
+import org.oscim.core.GeoPoint;
+import org.oscim.event.Event;
+import org.oscim.event.Gesture;
+import org.oscim.event.GestureListener;
+import org.oscim.event.MotionEvent;
+import org.oscim.layers.Layer;
+import org.oscim.map.Map;
+import org.osmdroid.overlays.MapEventsReceiver;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class DistanceTouchOverlay extends Layer implements Map.InputListener,
+        GestureListener {
+
+    private static final int LONGPRESS_THRESHOLD = 800;
+
+    private Timer mLongpressTimer;
+
+    private float mPrevX1, mPrevX2, mPrevY1, mPrevY2;
+    private float mCurX1, mCurX2, mCurY1, mCurY2;
+
+    // private final static int POINTER_UP = -1;
+    // private int mPointer1 = POINTER_UP;
+    // private int mPointer2 = POINTER_UP;
+
+    private final MapEventsReceiver mReceiver;
+
+    /**
+     * @param map      the Map
+     * @param receiver the object that will receive/handle the events. It must
+     *                 implement MapEventsReceiver interface.
+     */
+    public DistanceTouchOverlay(Map map, MapEventsReceiver receiver) {
+        super(map);
+        mReceiver = receiver;
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+    }
+
+    private void cancel() {
+
+        if (mLongpressTimer != null) {
+            mLongpressTimer.cancel();
+            mLongpressTimer = null;
+        }
+    }
+
+    @Override
+    public void onInputEvent(Event event, MotionEvent e) {
+
+        int action = e.getAction() & MotionEvent.ACTION_MASK;
+
+        if ((action == MotionEvent.ACTION_CANCEL)) {
+            cancel();
+            return;
+        }
+
+        if (mLongpressTimer != null) {
+            // any pointer up while long press detection
+            // cancels timer
+            if (action == MotionEvent.ACTION_POINTER_UP
+                    || action == MotionEvent.ACTION_UP) {
+
+                cancel();
+                return;
+            }
+
+            // two fingers must still be down, tested
+            // one above.
+            if (action == MotionEvent.ACTION_MOVE) {
+                // update pointer positions
+                // int idx1 = e.findPointerIndex(mPointer1);
+                // int idx2 = e.findPointerIndex(mPointer2);
+
+                mCurX1 = e.getX(0);
+                mCurY1 = e.getY(0);
+                mCurX2 = e.getX(1);
+                mCurY2 = e.getY(1);
+
+                // cancel if moved one finger more than 50 pixel
+                float maxSq = 10 * 10;
+                float d = (mCurX1 - mPrevX1) * (mCurX1 - mPrevX1)
+                        + (mCurY1 - mPrevY1) * (mCurY1 - mPrevY1);
+                if (d > maxSq) {
+                    cancel();
+                    return;
+                }
+                d = (mCurX2 - mPrevX2) * (mCurX2 - mPrevX2)
+                        + (mCurY2 - mPrevY2) * (mCurY2 - mPrevY2);
+                if (d > maxSq) {
+                    cancel();
+                    return;
+                }
+            }
+        }
+
+        if ((action == MotionEvent.ACTION_POINTER_DOWN)
+                && (e.getPointerCount() == 2)) {
+            // App.log.debug("down");
+
+            // keep track of pointer ids, only
+            // use these for gesture, ignoring
+            // more than two pointer
+
+            // mPointer1 = e.getPointerId(0);
+            // mPointer2 = e.getPointerId(1);
+
+            if (mLongpressTimer == null) {
+                // start timer, keep initial down position
+                mCurX1 = mPrevX1 = e.getX(0);
+                mCurY1 = mPrevY1 = e.getY(0);
+                mCurX2 = mPrevX2 = e.getX(1);
+                mCurY2 = mPrevY2 = e.getY(1);
+                runLongpressTimer();
+            }
+        }
+    }
+
+    // @Override
+    // public boolean onLongPress(MotionEvent e) {
+    // // dont forward long press when two fingers are down.
+    // // maybe should be only done if our timer is still running.
+    // // ... not sure if this is even needed
+    // GeoPoint p = mMap.getViewport().fromScreenPoint(e.getX(), e.getY());
+    // return mReceiver.longPressHelper(p);
+    // }
+
+    public void runLongpressTimer() {
+        // mMap.postDelayed(action, delay);
+
+        mLongpressTimer = new Timer();
+        mLongpressTimer.schedule(new TimerTask() {
+
+            @Override
+            public void run() {
+                final GeoPoint p1 = mMap.viewport().fromScreenPoint(mCurX1,
+                        mCurY1);
+                final GeoPoint p2 = mMap.viewport().fromScreenPoint(mCurX2,
+                        mCurY2);
+
+                mMap.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mReceiver.longPressHelper(p1, p2);
+                    }
+                });
+            }
+        }, LONGPRESS_THRESHOLD);
+    }
+
+    @Override
+    public boolean onGesture(Gesture g, MotionEvent e) {
+        if (g instanceof Gesture.LongPress) {
+            GeoPoint p = mMap.viewport().fromScreenPoint(e.getX(), e.getY());
+            return mReceiver.longPressHelper(p);
+        }
+        return false;
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/location/FlickrPOIProvider.java b/vtm-app/src/org/osmdroid/location/FlickrPOIProvider.java
new file mode 100644
index 00000000..e33f3d32
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/FlickrPOIProvider.java
@@ -0,0 +1,163 @@
+package org.osmdroid.location;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.utils.BonusPackHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * POI Provider using Flickr service to get geolocalized photos.
+ *
+ * @author M.Kergall
+ * @see "http://www.flickr.com/services/api/flickr.photos.search.html"
+ */
+public class FlickrPOIProvider implements POIProvider {
+
+    final static Logger log = LoggerFactory.getLogger(FlickrPOIProvider.class);
+
+    protected String mApiKey;
+    private final static String PHOTO_URL = "http://www.flickr.com/photos/%s/%s/sizes/o/in/photostream/";
+
+    /**
+     * @param apiKey the registered API key to give to Flickr service.
+     * @see "http://www.flickr.com/help/api/"
+     */
+    public FlickrPOIProvider(String apiKey) {
+        mApiKey = apiKey;
+    }
+
+    private String getUrlInside(BoundingBox boundingBox, int maxResults) {
+        StringBuffer url = new StringBuffer(
+                "http://api.flickr.com/services/rest/?method=flickr.photos.search");
+        url.append("&api_key=" + mApiKey);
+        url.append("&bbox=" + boundingBox.getMinLongitude());
+        url.append("," + boundingBox.getMinLatitude());
+        url.append("," + boundingBox.getMaxLongitude());
+        url.append("," + boundingBox.getMaxLatitude());
+        url.append("&has_geo=1");
+        // url.append("&geo_context=2");
+        // url.append("&is_commons=true");
+        url.append("&format=json&nojsoncallback=1");
+        url.append("&per_page=" + maxResults);
+        // From Flickr doc:
+        // "Geo queries require some sort of limiting agent in order to prevent the database from crying."
+        // And min_date_upload is considered as a limiting agent. So:
+        url.append("&min_upload_date=2005/01/01");
+
+        // Ask to provide some additional attributes we will need:
+        url.append("&extras=geo,url_sq");
+        url.append("&sort=interestingness-desc");
+        return url.toString();
+    }
+
+    /* public POI getPhoto(String photoId){ String url =
+     * "http://api.flickr.com/services/rest/?method=flickr.photos.getInfo"
+     * +
+     * "&api_key=" + mApiKey + "&photo_id=" + photo Id +
+     * "&format=json&nojsoncallback=1"; log.debug( * "getPhoto:"+url); String
+     * jString =
+     * BonusPackHelper.requestStringFromUrl(url); if (jString == null)
+     * {
+     * log.error( * "FlickrPOIProvider: request failed.");
+     * return null; } try { POI poi = new POI(POI.POI_SERVICE_FLICKR);
+     * JSONObject jRoot = new JSONObject(jString); JSONObject jPhoto =
+     * jRoot.getJSONObject("photo"); JSONObject jLocation =
+     * jPhoto.getJSONObject("location"); poi.mLocation = new GeoPoint(
+     * jLocation.getDouble("latitude"),
+     * jLocation.getDouble("longitude"));
+     * poi.mId = Long.parseLong(photoId); JSONObject jTitle =
+     * jPhoto.getJSONObject("title"); poi.mType =
+     * jTitle.getString("_content");
+     * JSONObject jDescription = jPhoto.getJSONObject("description");
+     * poi.mDescription = jDescription.getString("_content");
+     * //truncate
+     * description if too long: if (poi.mDescription.length() > 300){
+     * poi.mDescription = poi.mDescription.substring(0, 300) +
+     * " (...)"; }
+     * String farm = jPhoto.getString("farm"); String server =
+     * jPhoto.getString("server"); String secret =
+     * jPhoto.getString("secret");
+     * JSONObject jOwner = jPhoto.getJSONObject("owner"); String nsid
+     * =
+     * jOwner.getString("nsid"); poi.mThumbnailPath =
+     * "http://farm"+farm+".staticflickr.com/"
+     * +server+"/"+photoId+"_"+secret+"_s.jpg"; poi.mUrl =
+     * "http://www.flickr.com/photos/"+nsid+"/"+photoId; return poi;
+     * }catch
+     * (JSONException e) { e.printStackTrace(); return null; } } */
+
+    /**
+     * @param fullUrl ...
+     * @return the list of POI
+     */
+    public ArrayList<POI> getThem(String fullUrl) {
+        // for local debug: fullUrl = "http://10.0.2.2/flickr_mockup.json";
+        log.debug("FlickrPOIProvider:get:" + fullUrl);
+        String jString = BonusPackHelper.requestStringFromUrl(fullUrl);
+        if (jString == null) {
+            log.error("FlickrPOIProvider: request failed.");
+            return null;
+        }
+        try {
+            JSONObject jRoot = new JSONObject(jString);
+            JSONObject jPhotos = jRoot.getJSONObject("photos");
+            JSONArray jPhotoArray = jPhotos.getJSONArray("photo");
+            int n = jPhotoArray.length();
+            ArrayList<POI> pois = new ArrayList<POI>(n);
+            for (int i = 0; i < n; i++) {
+                JSONObject jPhoto = jPhotoArray.getJSONObject(i);
+
+                String photoId = jPhoto.getString("id");
+                if (mPrevious != null && mPrevious.containsKey(photoId))
+                    continue;
+
+                POI poi = new POI(POI.POI_SERVICE_FLICKR);
+                poi.location = new GeoPoint(
+                        jPhoto.getDouble("latitude"),
+                        jPhoto.getDouble("longitude"));
+                poi.id = photoId; //Long.parseLong(photoId);
+                poi.type = jPhoto.getString("title");
+                poi.thumbnailPath = jPhoto.getString("url_sq");
+                String owner = jPhoto.getString("owner");
+                // the default flickr link viewer doesnt work with mobile browsers...
+                //    poi.url = "http://www.flickr.com/photos/" + owner + "/" + photoId + "/sizes/o/in/photostream/";
+
+                poi.url = String.format(PHOTO_URL, owner, photoId);
+
+                pois.add(poi);
+            }
+            //            int total = jPhotos.getInt("total");
+            //            log.debug(on a total of:" + total);
+            return pois;
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * @param boundingBox ...
+     * @param maxResults  ...
+     * @return list of POI, Flickr photos inside the bounding box.
+     * Null if
+     * technical issue.
+     */
+    public ArrayList<POI> getPOIInside(BoundingBox boundingBox, String query, int maxResults) {
+        String url = getUrlInside(boundingBox, maxResults);
+        return getThem(url);
+    }
+
+    HashMap<String, POI> mPrevious;
+
+    public void setPrevious(HashMap<String, POI> previous) {
+        mPrevious = previous;
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/location/FourSquareProvider.java b/vtm-app/src/org/osmdroid/location/FourSquareProvider.java
new file mode 100644
index 00000000..4035bbfd
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/FourSquareProvider.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2012 Hannes Janetzek
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.osmdroid.location;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.utils.BonusPackHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+public class FourSquareProvider implements POIProvider {
+
+    final static Logger log = LoggerFactory.getLogger(FourSquareProvider.class);
+
+    //    https://developer.foursquare.com/docs/venues/search
+    //    https://developer.foursquare.com/docs/responses/venue
+    //    https://apigee.com/console/foursquare
+
+    protected String mApiKey;
+
+    //    private static HashMap<String, Bitmap> mIcons =
+    //            (HashMap<String,Bitmap>)Collections.synchronizedMap(new HashMap<String, Bitmap>());
+
+    /**
+     * @param clientSecret the registered API key to give to Flickr service.
+     * @see "http://www.flickr.com/help/api/"
+     */
+    public FourSquareProvider(String clientId, String clientSecret) {
+        mApiKey = "client_id=" + clientId + "&client_secret=" + clientSecret;
+    }
+
+    //"https://api.foursquare.com/v2/venues/search?v=20120321&intent=checkin&ll=53.06,8.8&client_id=ZUN4ZMNZUFT3Z5QQZNMQ3ACPL4OJMBFGO15TYX51D5MHCIL3&client_secret=X1RXCVF4VVSG1Y2FUDQJLKQUC1WF4XXKIMK2STXKACLPDGLY
+    @SuppressWarnings("deprecation")
+    private String getUrlInside(BoundingBox boundingBox, String query, int maxResults) {
+        StringBuffer url = new StringBuffer(
+                "https://api.foursquare.com/v2/venues/search?v=20120321"
+                        + "&intent=browse"
+                        + "&client_id=ZUN4ZMNZUFT3Z5QQZNMQ3ACPL4OJMBFGO15TYX51D5MHCIL3"
+                        + "&client_secret=X1RXCVF4VVSG1Y2FUDQJLKQUC1WF4XXKIMK2STXKACLPDGLY");
+        url.append("&sw=");
+        url.append(boundingBox.getMinLatitude());
+        url.append(',');
+        url.append(boundingBox.getMinLongitude());
+        url.append("&ne=");
+        url.append(boundingBox.getMaxLatitude());
+        url.append(',');
+        url.append(boundingBox.getMaxLongitude());
+        url.append("&limit=");
+        url.append(maxResults);
+        if (query != null)
+            url.append("&query=" + URLEncoder.encode(query));
+        return url.toString();
+    }
+
+    /**
+     * @param fullUrl ...
+     * @return the list of POI
+     */
+    public ArrayList<POI> getThem(String fullUrl) {
+        // for local debug: fullUrl = "http://10.0.2.2/flickr_mockup.json";
+        log.debug("FlickrPOIProvider:get:" + fullUrl);
+        String jString = BonusPackHelper.requestStringFromUrl(fullUrl);
+        if (jString == null) {
+            log.error("FlickrPOIProvider: request failed.");
+            return null;
+        }
+        try {
+            JSONObject jRoot = new JSONObject(jString);
+
+            JSONObject jResponse = jRoot.getJSONObject("response");
+            JSONArray jVenueArray = jResponse.getJSONArray("venues");
+            int n = jVenueArray.length();
+            ArrayList<POI> pois = new ArrayList<POI>(n);
+            for (int i = 0; i < n; i++) {
+                JSONObject jVenue = jVenueArray.getJSONObject(i);
+
+                POI poi = new POI(POI.POI_SERVICE_4SQUARE);
+                poi.id = jVenue.getString("id");
+                poi.type = jVenue.getString("name");
+                //                poi.url = jVenue.optString("url", null);
+                poi.url = "https://foursquare.com/v/" + poi.id;
+
+                JSONObject jLocation = jVenue.getJSONObject("location");
+                poi.location = new GeoPoint(
+                        jLocation.getDouble("lat"),
+                        jLocation.getDouble("lng"));
+                poi.description = jLocation.optString("address", null);
+
+                JSONArray jCategories = jVenue.getJSONArray("categories");
+                if (jCategories.length() > 0) {
+                    JSONObject jCategory = jCategories.getJSONObject(0);
+                    String icon = jCategory.getJSONObject("icon").getString("prefix");
+                    poi.thumbnailPath = icon + 44 + ".png";
+                    poi.category = jCategory.optString("name");
+                }
+                pois.add(poi);
+            }
+
+            return pois;
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * @param boundingBox ...
+     * @param maxResults  ...
+     * @return list of POI, Flickr photos inside the bounding box.
+     * Null if
+     * technical issue.
+     */
+    public ArrayList<POI> getPOIInside(BoundingBox boundingBox, String query, int maxResults) {
+        String url = getUrlInside(boundingBox, query, maxResults);
+        return getThem(url);
+    }
+
+    public static void browse(final Context context, POI poi) {
+        // get the right url from redirect, could also parse the result from querying venueid...
+        new AsyncTask<POI, Void, String>() {
+
+            @Override
+            protected String doInBackground(POI... params) {
+                POI poi = params[0];
+                if (poi == null)
+                    return null;
+                try {
+                    URL url = new URL(poi.url);
+                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+                    conn.setInstanceFollowRedirects(false);
+
+                    String redirect = conn.getHeaderField("Location");
+                    if (redirect != null) {
+                        log.debug(redirect);
+                        return redirect;
+                    }
+                } catch (MalformedURLException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+
+                return null;
+            }
+
+            @Override
+            protected void onPostExecute(String result) {
+                if (result == null)
+                    return;
+
+                Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://foursquare.com"
+                        + result));
+                context.startActivity(myIntent);
+
+            }
+        }.execute(poi);
+
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/location/GeoNamesPOIProvider.java b/vtm-app/src/org/osmdroid/location/GeoNamesPOIProvider.java
new file mode 100644
index 00000000..24d09bd0
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/GeoNamesPOIProvider.java
@@ -0,0 +1,215 @@
+package org.osmdroid.location;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.utils.BonusPackHelper;
+import org.osmdroid.utils.HttpConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * POI Provider using GeoNames services. Currently, "find Nearby Wikipedia" and
+ * "Wikipedia Articles in Bounding Box" services.
+ *
+ * @author M.Kergall
+ * @see "http://www.geonames.org"
+ */
+public class GeoNamesPOIProvider {
+
+    final static Logger log = LoggerFactory.getLogger(GeoNamesPOIProvider.class);
+
+    protected String mUserName;
+
+    /**
+     * @param account the registered "username" to give to GeoNames service.
+     * @see "http://www.geonames.org/login"
+     */
+    public GeoNamesPOIProvider(String account) {
+        mUserName = account;
+    }
+
+    private String getUrlCloseTo(GeoPoint p, int maxResults, double maxDistance) {
+        StringBuffer url = new StringBuffer("http://api.geonames.org/findNearbyWikipediaJSON?");
+        url.append("lat=" + p.getLatitude());
+        url.append("&lng=" + p.getLongitude());
+        url.append("&maxRows=" + maxResults);
+        url.append("&radius=" + maxDistance); //km
+        url.append("&lang=" + Locale.getDefault().getLanguage());
+        url.append("&username=" + mUserName);
+        return url.toString();
+    }
+
+    private String getUrlInside(BoundingBox boundingBox, int maxResults) {
+        StringBuffer url = new StringBuffer("http://api.geonames.org/wikipediaBoundingBoxJSON?");
+        url.append("south=" + boundingBox.getMinLatitude());
+        url.append("&north=" + boundingBox.getMaxLatitude());
+        url.append("&west=" + boundingBox.getMinLongitude());
+        url.append("&east=" + boundingBox.getMaxLongitude());
+        url.append("&maxRows=" + maxResults);
+        url.append("&lang=" + Locale.getDefault().getLanguage());
+        url.append("&username=" + mUserName);
+        return url.toString();
+    }
+
+    /**
+     * @param fullUrl ...
+     * @return the list of POI
+     */
+    public ArrayList<POI> getThem(String fullUrl) {
+        log.debug("GeoNamesPOIProvider:get:" + fullUrl);
+        String jString = BonusPackHelper.requestStringFromUrl(fullUrl);
+        if (jString == null) {
+            log.error("GeoNamesPOIProvider: request failed.");
+            return null;
+        }
+        try {
+            JSONObject jRoot = new JSONObject(jString);
+            JSONArray jPlaceIds = jRoot.getJSONArray("geonames");
+            int n = jPlaceIds.length();
+            ArrayList<POI> pois = new ArrayList<POI>(n);
+            for (int i = 0; i < n; i++) {
+                JSONObject jPlace = jPlaceIds.getJSONObject(i);
+                POI poi = new POI(POI.POI_SERVICE_GEONAMES_WIKIPEDIA);
+                poi.location = new GeoPoint(jPlace.getDouble("lat"),
+                        jPlace.getDouble("lng"));
+                poi.category = jPlace.optString("feature");
+                poi.type = jPlace.getString("title");
+                poi.description = jPlace.optString("summary");
+                poi.thumbnailPath = jPlace.optString("thumbnailImg", null);
+                /* This makes loading too long. Thumbnail loading will be done
+                 * only when needed, with POI.getThumbnail() if
+                 * (poi.mThumbnailPath != null){ poi.mThumbnail =
+                 * BonusPackHelper.loadBitmap(poi.mThumbnailPath); } */
+                poi.url = jPlace.optString("wikipediaUrl", null);
+                if (poi.url != null)
+                    poi.url = "http://" + poi.url;
+                poi.rank = jPlace.optInt("rank", 0);
+                //other attributes: distance?
+                pois.add(poi);
+            }
+            log.debug("done");
+            return pois;
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    //XML parsing seems 2 times slower than JSON parsing
+    public ArrayList<POI> getThemXML(String fullUrl) {
+        log.debug("GeoNamesPOIProvider:get:" + fullUrl);
+        HttpConnection connection = new HttpConnection();
+        connection.doGet(fullUrl);
+        InputStream stream = connection.getStream();
+        if (stream == null) {
+            return null;
+        }
+        GeoNamesXMLHandler handler = new GeoNamesXMLHandler();
+        try {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            parser.parse(stream, handler);
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        } catch (SAXException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        connection.close();
+        log.debug("done");
+        return handler.mPOIs;
+    }
+
+    /**
+     * @param position    ...
+     * @param maxResults  ...
+     * @param maxDistance ... in km. 20 km max for the free service.
+     * @return list of POI, Wikipedia entries close to the position. Null if
+     * technical issue.
+     */
+    public ArrayList<POI> getPOICloseTo(GeoPoint position,
+                                        int maxResults, double maxDistance) {
+        String url = getUrlCloseTo(position, maxResults, maxDistance);
+        return getThem(url);
+    }
+
+    /**
+     * @param boundingBox ...
+     * @param maxResults  ...
+     * @return list of POI, Wikipedia entries inside the bounding box. Null if
+     * technical issue.
+     */
+    public ArrayList<POI> getPOIInside(BoundingBox boundingBox, int maxResults) {
+        String url = getUrlInside(boundingBox, maxResults);
+        return getThem(url);
+    }
+}
+
+class GeoNamesXMLHandler extends DefaultHandler {
+
+    private String mString;
+    double mLat, mLng;
+    POI mPOI;
+    ArrayList<POI> mPOIs;
+
+    public GeoNamesXMLHandler() {
+        mPOIs = new ArrayList<POI>();
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String name,
+                             Attributes attributes) {
+        if (localName.equals("entry")) {
+            mPOI = new POI(POI.POI_SERVICE_GEONAMES_WIKIPEDIA);
+        }
+        mString = new String();
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) {
+        String chars = new String(ch, start, length);
+        mString = mString.concat(chars);
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String name) {
+        if (localName.equals("lat")) {
+            mLat = Double.parseDouble(mString);
+        } else if (localName.equals("lng")) {
+            mLng = Double.parseDouble(mString);
+        } else if (localName.equals("feature")) {
+            mPOI.category = mString;
+        } else if (localName.equals("title")) {
+            mPOI.type = mString;
+        } else if (localName.equals("summary")) {
+            mPOI.description = mString;
+        } else if (localName.equals("thumbnailImg")) {
+            if (mString != null && !mString.equals(""))
+                mPOI.thumbnailPath = mString;
+        } else if (localName.equals("wikipediaUrl")) {
+            if (mString != null && !mString.equals(""))
+                mPOI.url = "http://" + mString;
+        } else if (localName.equals("rank")) {
+            mPOI.rank = Integer.parseInt(mString);
+        } else if (localName.equals("entry")) {
+            mPOI.location = new GeoPoint(mLat, mLng);
+            mPOIs.add(mPOI);
+        }
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/location/GeocoderNominatim.java b/vtm-app/src/org/osmdroid/location/GeocoderNominatim.java
new file mode 100644
index 00000000..6ea92210
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/GeocoderNominatim.java
@@ -0,0 +1,208 @@
+package org.osmdroid.location;
+
+import android.content.Context;
+import android.location.Address;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.osmdroid.utils.BonusPackHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Implements an equivalent to Android Geocoder class, based on OpenStreetMap
+ * data and Nominatim API. <br>
+ * See http://wiki.openstreetmap.org/wiki/Nominatim or
+ * http://open.mapquestapi.com/nominatim/
+ *
+ * @author M.Kergall
+ */
+public class GeocoderNominatim {
+
+    final static Logger log = LoggerFactory.getLogger(GeocoderNominatim.class);
+
+    public static final String NOMINATIM_SERVICE_URL = "http://nominatim.openstreetmap.org/";
+    public static final String MAPQUEST_SERVICE_URL = "http://open.mapquestapi.com/nominatim/v1/";
+
+    protected Locale mLocale;
+    protected String mServiceUrl;
+
+    /**
+     * @param context ...
+     * @param locale  ...
+     */
+    protected void init(Context context, Locale locale) {
+        mLocale = locale;
+        setService(NOMINATIM_SERVICE_URL); //default service
+    }
+
+    public GeocoderNominatim(Context context, Locale locale) {
+        init(context, locale);
+    }
+
+    public GeocoderNominatim(Context context) {
+        init(context, Locale.getDefault());
+    }
+
+    static public boolean isPresent() {
+        return true;
+    }
+
+    /**
+     * Specify the url of the Nominatim service provider to use. Can be one of
+     * the predefined (NOMINATIM_SERVICE_URL or MAPQUEST_SERVICE_URL), or
+     * another one, your local instance of Nominatim for instance.
+     *
+     * @param serviceUrl ...
+     */
+    public void setService(String serviceUrl) {
+        mServiceUrl = serviceUrl;
+    }
+
+    /**
+     * Build an Android Address object from the Nominatim address in JSON
+     * format. Current implementation is mainly targeting french addresses, and
+     * will be quite basic on other countries.
+     *
+     * @param jResult ...
+     * @return ...
+     * @throws JSONException ...
+     */
+    protected Address buildAndroidAddress(JSONObject jResult) throws JSONException {
+        Address gAddress = new Address(mLocale);
+        gAddress.setLatitude(jResult.getDouble("lat"));
+        gAddress.setLongitude(jResult.getDouble("lon"));
+
+        JSONObject jAddress = jResult.getJSONObject("address");
+
+        int addressIndex = 0;
+        if (jAddress.has("road")) {
+            gAddress.setAddressLine(addressIndex++, jAddress.getString("road"));
+            gAddress.setThoroughfare(jAddress.getString("road"));
+        }
+        if (jAddress.has("suburb")) {
+            //gAddress.setAddressLine(addressIndex++, jAddress.getString("suburb"));
+            //not kept => often introduce "noise" in the address.
+            gAddress.setSubLocality(jAddress.getString("suburb"));
+        }
+        if (jAddress.has("postcode")) {
+            gAddress.setAddressLine(addressIndex++, jAddress.getString("postcode"));
+            gAddress.setPostalCode(jAddress.getString("postcode"));
+        }
+
+        if (jAddress.has("city")) {
+            gAddress.setAddressLine(addressIndex++, jAddress.getString("city"));
+            gAddress.setLocality(jAddress.getString("city"));
+        } else if (jAddress.has("town")) {
+            gAddress.setAddressLine(addressIndex++, jAddress.getString("town"));
+            gAddress.setLocality(jAddress.getString("town"));
+        } else if (jAddress.has("village")) {
+            gAddress.setAddressLine(addressIndex++, jAddress.getString("village"));
+            gAddress.setLocality(jAddress.getString("village"));
+        }
+
+        if (jAddress.has("county")) { //France: departement
+            gAddress.setSubAdminArea(jAddress.getString("county"));
+        }
+        if (jAddress.has("state")) { //France: region
+            gAddress.setAdminArea(jAddress.getString("state"));
+        }
+        if (jAddress.has("country")) {
+            gAddress.setAddressLine(addressIndex++, jAddress.getString("country"));
+            gAddress.setCountryName(jAddress.getString("country"));
+        }
+        if (jAddress.has("country_code"))
+            gAddress.setCountryCode(jAddress.getString("country_code"));
+
+        /* Other possible OSM tags in Nominatim results not handled yet: subway,
+         * golf_course, bus_stop, parking,... house, house_number, building
+         * city_district (13e Arrondissement) road => or highway, ... sub-city
+         * (like suburb) => locality, isolated_dwelling, hamlet ...
+         * state_district */
+
+        return gAddress;
+    }
+
+    /**
+     * @param latitude   ...
+     * @param longitude  ...
+     * @param maxResults ...
+     * @return ...
+     * @throws IOException ...
+     */
+    public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
+            throws IOException {
+        String url = mServiceUrl
+                + "reverse?"
+                + "format=json"
+                + "&accept-language=" + mLocale.getLanguage()
+                //+ "&addressdetails=1"
+                + "&lat=" + latitude
+                + "&lon=" + longitude;
+        log.debug("GeocoderNominatim::getFromLocation:" + url);
+        String result = BonusPackHelper.requestStringFromUrl(url);
+        //log.debug(result);
+        if (result == null)
+            throw new IOException();
+        try {
+            JSONObject jResult = new JSONObject(result);
+            Address gAddress = buildAndroidAddress(jResult);
+            List<Address> list = new ArrayList<Address>();
+            list.add(gAddress);
+            return list;
+        } catch (JSONException e) {
+            throw new IOException();
+        }
+    }
+
+    public List<Address> getFromLocationName(String locationName, int maxResults,
+                                             double lowerLeftLatitude, double lowerLeftLongitude,
+                                             double upperRightLatitude, double upperRightLongitude)
+            throws IOException {
+        String url = mServiceUrl
+                + "search?"
+                + "format=json"
+                + "&accept-language=" + mLocale.getLanguage()
+                + "&addressdetails=1"
+                + "&limit=" + maxResults
+                + "&q=" + URLEncoder.encode(locationName, "UTF-8");
+        if (lowerLeftLatitude != 0.0 && lowerLeftLongitude != 0.0) {
+            //viewbox = left, top, right, bottom:
+            url += "&viewbox=" + lowerLeftLongitude
+                    + "," + upperRightLatitude
+                    + "," + upperRightLongitude
+                    + "," + lowerLeftLatitude
+                    + "&bounded=1";
+        }
+        log.debug("GeocoderNominatim::getFromLocationName:" + url);
+        String result = BonusPackHelper.requestStringFromUrl(url);
+        //log.debug(result);
+        if (result == null)
+            throw new IOException();
+        try {
+            JSONArray jResults = new JSONArray(result);
+            List<Address> list = new ArrayList<Address>();
+            for (int i = 0; i < jResults.length(); i++) {
+                JSONObject jResult = jResults.getJSONObject(i);
+                Address gAddress = buildAndroidAddress(jResult);
+                list.add(gAddress);
+            }
+            return list;
+        } catch (JSONException e) {
+            throw new IOException();
+        }
+    }
+
+    public List<Address> getFromLocationName(String locationName, int maxResults)
+            throws IOException {
+        return getFromLocationName(locationName, maxResults, 0.0, 0.0, 0.0, 0.0);
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/location/NominatimPOIProvider.java b/vtm-app/src/org/osmdroid/location/NominatimPOIProvider.java
new file mode 100644
index 00000000..09ea46ff
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/NominatimPOIProvider.java
@@ -0,0 +1,192 @@
+package org.osmdroid.location;
+
+import android.graphics.Bitmap;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.utils.BonusPackHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+/**
+ * POI Provider using Nominatim service. <br>
+ * See https://wiki.openstreetmap.org/wiki/Nominatim<br>
+ * and http://open.mapquestapi.com/nominatim/<br>
+ *
+ * @author M.Kergall
+ */
+public class NominatimPOIProvider implements POIProvider {
+
+    final static Logger log = LoggerFactory.getLogger(NominatimPOIProvider.class);
+
+    /* As the doc lacks a lot of features, source code may help:
+     * https://trac.openstreetmap
+     * .org/browser/applications/utils/nominatim/website/search.php featuretype=
+     * to select on feature type (country, city, state, settlement)<br>
+     * format=jsonv2 to get a place_rank<br> offset= to offset the result ?...
+     * <br> polygon=1 to get the border of the poi as a polygon<br> nearlat &
+     * nearlon = ???<br> routewidth/69 and routewidth/30 ???<br> */
+    public static final String MAPQUEST_POI_SERVICE = "http://open.mapquestapi.com/nominatim/v1/";
+    public static final String NOMINATIM_POI_SERVICE = "http://nominatim.openstreetmap.org/";
+    protected String mService;
+
+    public NominatimPOIProvider() {
+        mService = NOMINATIM_POI_SERVICE;
+    }
+
+    public void setService(String serviceUrl) {
+        mService = serviceUrl;
+    }
+
+    @SuppressWarnings("deprecation")
+    private StringBuffer getCommonUrl(String type, int maxResults) {
+        StringBuffer urlString = new StringBuffer(mService);
+        urlString.append("search?");
+        urlString.append("format=json");
+        urlString.append("&q=" + URLEncoder.encode(type));
+        urlString.append("&limit=" + maxResults);
+        //urlString.append("&bounded=1");
+        //        urlString.append("&addressdetails=0");
+        return urlString;
+    }
+
+    private String getUrlInside(BoundingBox bb, String type, int maxResults) {
+        StringBuffer urlString = getCommonUrl(type, maxResults);
+        urlString.append("&viewbox=" + bb.getMaxLongitude() + ","
+                + bb.getMaxLatitude() + ","
+                + bb.getMinLongitude() + ","
+                + bb.getMinLatitude());
+        return urlString.toString();
+    }
+
+    private String getUrlCloseTo(GeoPoint p, String type,
+                                 int maxResults, double maxDistance) {
+        int maxD = (int) (maxDistance * 1E6);
+        BoundingBox bb = new BoundingBox(p.latitudeE6 + maxD,
+                p.longitudeE6 + maxD,
+                p.latitudeE6 - maxD,
+                p.longitudeE6 - maxD);
+        return getUrlInside(bb, type, maxResults);
+    }
+
+    /**
+     * @param url full URL request
+     * @return the list of POI, of null if technical issue.
+     */
+    public ArrayList<POI> getThem(String url) {
+        log.debug("NominatimPOIProvider:get:" + url);
+        String jString = BonusPackHelper.requestStringFromUrl(url);
+        if (jString == null) {
+            log.error("NominatimPOIProvider: request failed.");
+            return null;
+        }
+        try {
+            JSONArray jPlaceIds = new JSONArray(jString);
+            int n = jPlaceIds.length();
+            ArrayList<POI> pois = new ArrayList<POI>(n);
+            Bitmap thumbnail = null;
+            for (int i = 0; i < n; i++) {
+                JSONObject jPlace = jPlaceIds.getJSONObject(i);
+                POI poi = new POI(POI.POI_SERVICE_NOMINATIM);
+                poi.id = jPlace.getString("osm_id");
+                //    jPlace.optLong("osm_id");
+                poi.location = new GeoPoint(jPlace.getDouble("lat"), jPlace.getDouble("lon"));
+                JSONArray bbox = jPlace.optJSONArray("boundingbox");
+                if (bbox != null) {
+                    try {
+                        poi.bbox = new BoundingBox(bbox.getDouble(0), bbox.getDouble(2),
+                                bbox.getDouble(1), bbox.getDouble(3));
+                    } catch (Exception e) {
+                        log.debug("could not parse " + bbox);
+                    }
+                    //log.debug("bbox " + poi.bbox);
+                }
+                poi.category = jPlace.optString("class");
+                poi.type = jPlace.getString("type");
+                poi.description = jPlace.optString("display_name");
+                poi.thumbnailPath = jPlace.optString("icon", null);
+
+                if (i == 0 && poi.thumbnailPath != null) {
+                    //first POI, and we have a thumbnail: load it
+                    thumbnail = BonusPackHelper.loadBitmap(poi.thumbnailPath);
+                }
+                poi.thumbnail = thumbnail;
+                pois.add(poi);
+            }
+            return pois;
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * @param position    ...
+     * @param type        an OpenStreetMap feature. See
+     *                    http://wiki.openstreetmap.org/wiki/Map_Features or
+     *                    http://code.google.com/p/osmbonuspack/source/browse/trunk/
+     *                    OSMBonusPackDemo/res/values/poi_tags.xml
+     * @param maxResults  the maximum number of POI returned. Note that in any case,
+     *                    Nominatim will have an absolute maximum of 100.
+     * @param maxDistance to the position, in degrees. Note that it is used to build a
+     *                    bounding box around the position, not a circle.
+     * @return the list of POI, null if technical issue.
+     */
+    public ArrayList<POI> getPOICloseTo(GeoPoint position, String type,
+                                        int maxResults, double maxDistance) {
+        String url = getUrlCloseTo(position, type, maxResults, maxDistance);
+        return getThem(url);
+    }
+
+    /**
+     * @param boundingBox ...
+     * @param type        OpenStreetMap feature
+     * @param maxResults  ...
+     * @return list of POIs, null if technical issue.
+     */
+    public ArrayList<POI> getPOIInside(BoundingBox boundingBox, String type, int maxResults) {
+        String url = getUrlInside(boundingBox, type, maxResults);
+        return getThem(url);
+    }
+
+    public ArrayList<POI> getPOI(String query, int maxResults) {
+        String url = getCommonUrl(query, maxResults).toString();
+        return getThem(url);
+    }
+
+    /**
+     * @param path       Warning: a long path may cause a failure due to the url to be
+     *                   too long. Using a simplified route may help (see
+     *                   Road.getRouteLow()).
+     * @param type       OpenStreetMap feature
+     * @param maxResults ...
+     * @param maxWidth   to the path. Certainly not in degrees. Probably in km.
+     * @return list of POIs, null if technical issue.
+     */
+    public ArrayList<POI> getPOIAlong(ArrayList<GeoPoint> path, String type,
+                                      int maxResults, double maxWidth) {
+        StringBuffer urlString = getCommonUrl(type, maxResults);
+        urlString.append("&routewidth=" + maxWidth);
+        urlString.append("&route=");
+        boolean isFirst = true;
+        for (GeoPoint p : path) {
+            if (isFirst)
+                isFirst = false;
+            else
+                urlString.append(",");
+            String lat = Double.toString(p.getLatitude());
+            lat = lat.substring(0, Math.min(lat.length(), 7));
+            String lon = Double.toString(p.getLongitude());
+            lon = lon.substring(0, Math.min(lon.length(), 7));
+            urlString.append(lat + "," + lon);
+            //limit the size of url as much as possible, as post method is not supported.
+        }
+        return getThem(urlString.toString());
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/location/OverpassPOIProvider.java b/vtm-app/src/org/osmdroid/location/OverpassPOIProvider.java
new file mode 100644
index 00000000..b9bade53
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/OverpassPOIProvider.java
@@ -0,0 +1,67 @@
+package org.osmdroid.location;
+
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.oscim.core.Tag;
+import org.oscim.core.osm.OsmData;
+import org.oscim.core.osm.OsmNode;
+import org.oscim.utils.osmpbf.OsmPbfReader;
+import org.osmdroid.utils.HttpConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OverpassPOIProvider implements POIProvider {
+
+    final static Logger log = LoggerFactory
+            .getLogger(OverpassPOIProvider.class);
+
+    public static final String TAG_KEY_WEBSITE = "website".intern();
+
+    @Override
+    public List<POI> getPOIInside(BoundingBox boundingBox, String query,
+                                  int maxResults) {
+        HttpConnection connection = new HttpConnection();
+        boundingBox.toString();
+
+        String q = "node[\"amenity\"~\"^restaurant$|^pub$\"]("
+                + boundingBox.format() + ");out 100;";
+        String url = "http://city.informatik.uni-bremen.de/oapi/pbf?data=";
+        String encoded;
+        try {
+            encoded = URLEncoder.encode(q, "utf-8");
+        } catch (UnsupportedEncodingException e1) {
+            e1.printStackTrace();
+            return null;
+        }
+        log.debug("request " + url + encoded);
+        connection.doGet(url + encoded);
+        OsmData osmData = OsmPbfReader.process(connection.getStream());
+        ArrayList<POI> pois = new ArrayList<POI>(osmData.getNodes().size());
+
+        for (OsmNode n : osmData.getNodes()) {
+            POI p = new POI(POI.POI_SERVICE_4SQUARE);
+            p.id = Long.toString(n.id);
+
+            p.location = new GeoPoint(n.lat, n.lon);
+            Tag t;
+
+            if ((t = n.tags.get(Tag.KEY_NAME)) != null)
+                p.description = t.value;
+
+            if ((t = n.tags.get(Tag.KEY_AMENITY)) != null)
+                p.type = t.value;
+
+            if ((t = n.tags.get(TAG_KEY_WEBSITE)) != null) {
+                log.debug(p.description + " " + t.value);
+                p.url = t.value;
+            }
+            pois.add(p);
+        }
+        return pois;
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/location/POI.java b/vtm-app/src/org/osmdroid/location/POI.java
new file mode 100644
index 00000000..c796c9ff
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/POI.java
@@ -0,0 +1,205 @@
+package org.osmdroid.location;
+
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+import android.view.View;
+import android.widget.ImageView;
+
+import org.oscim.app.R;
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.utils.BonusPackHelper;
+
+/**
+ * Point of Interest. Exact content may depend of the POI provider used.
+ *
+ * @author M.Kergall
+ * @see NominatimPOIProvider
+ * @see GeoNamesPOIProvider
+ */
+public class POI {
+
+    /**
+     * IDs of POI services
+     */
+    public static int POI_SERVICE_NOMINATIM = 100;
+    public static int POI_SERVICE_GEONAMES_WIKIPEDIA = 200;
+    public static int POI_SERVICE_FLICKR = 300;
+    public static int POI_SERVICE_PICASA = 400;
+    public static int POI_SERVICE_4SQUARE = 500;
+
+    /**
+     * Identifies the service provider of this POI.
+     */
+    public int serviceId;
+    /**
+     * Nominatim: OSM ID. GeoNames: 0
+     */
+    public String id;
+    /**
+     * location of the POI
+     */
+    public GeoPoint location;
+    public BoundingBox bbox;
+    /**
+     * Nominatim "class", GeoNames "feature"
+     */
+    public String category;
+    /**
+     * type or title
+     */
+    public String type;
+    /**
+     * can be the name, the address, a short description
+     */
+    public String description;
+    /**
+     * url of the thumbnail. Null if none
+     */
+    public String thumbnailPath;
+    /**
+     * the thumbnail itself. Null if none
+     */
+    public Bitmap thumbnail;
+    /**
+     * url to a more detailed information page about this POI. Null if none
+     */
+    public String url;
+    /**
+     * popularity of this POI, from 1 (lowest) to 100 (highest). 0 if not
+     * defined.
+     */
+    public int rank;
+
+    /**
+     * number of attempts to load the thumbnail that have failed
+     */
+    protected int mThumbnailLoadingFailures;
+
+    public POI(int serviceId) {
+        this.serviceId = serviceId;
+        // lets all other fields empty or null. That's fine.
+    }
+
+    protected static int MAX_LOADING_ATTEMPTS = 2;
+
+    /**
+     * @return the POI thumbnail as a Bitmap, if any. If not done yet, it will
+     * load the POI thumbnail from its url (in thumbnailPath field).
+     */
+    public Bitmap getThumbnail() {
+        if (thumbnail == null && thumbnailPath != null) {
+            thumbnail = BonusPackHelper.loadBitmap(thumbnailPath);
+            if (thumbnail == null) {
+                mThumbnailLoadingFailures++;
+                if (mThumbnailLoadingFailures >= MAX_LOADING_ATTEMPTS) {
+                    // this path really doesn't work, "kill" it for next calls:
+                    thumbnailPath = null;
+                }
+            }
+        }
+        return thumbnail;
+    }
+
+    //    http://stackoverflow.com/questions/7729133/using-asynctask-to-load-images-in-listview
+    // TODO see link, there might be a better solution
+
+    /**
+     * Fetch the thumbnail from its url on a thread.
+     *
+     * @param imageView to update once the thumbnail is retrieved, or to hide if no
+     *                  thumbnail.
+     */
+    public void fetchThumbnail(final ImageView imageView) {
+        if (thumbnail != null) {
+            imageView.setImageBitmap(thumbnail);
+            imageView.setVisibility(View.VISIBLE);
+        } else if (thumbnailPath != null) {
+            imageView.setImageResource(R.drawable.ic_empty);
+            imageView.setVisibility(View.VISIBLE);
+            new ThumbnailTask(imageView).execute(imageView);
+        } else {
+            imageView.setVisibility(View.GONE);
+        }
+    }
+
+    class ThumbnailTask extends AsyncTask<ImageView, Void, ImageView> {
+
+        public ThumbnailTask(ImageView iv) {
+            iv.setTag(thumbnailPath);
+        }
+
+        @Override
+        protected ImageView doInBackground(ImageView... params) {
+            getThumbnail();
+            return params[0];
+        }
+
+        @Override
+        protected void onPostExecute(ImageView iv) {
+            if (iv == null || thumbnail == null)
+                return;
+            if (thumbnailPath.equals(iv.getTag().toString()))
+                iv.setImageBitmap(thumbnail);
+        }
+    }
+
+    // --- Parcelable implementation
+
+    //    @Override
+    //    public int describeContents() {
+    //        return 0;
+    //    }
+
+    //    @Override
+    //    public void writeToParcel(Parcel out, int flags) {
+    //        out.writeInt(serviceId);
+    //        out.writeString(id);
+    //        out.writeParcelable(location, 0);
+    //        out.writeString(category);
+    //        out.writeString(type);
+    //        out.writeString(description);
+    //        out.writeString(thumbnailPath);
+    //        out.writeParcelable(thumbnail, 0);
+    //        out.writeString(url);
+    //        out.writeInt(rank);
+    //        out.writeInt(mThumbnailLoadingFailures);
+    //    }
+    //
+    //    public static final Parcelable.Creator<POI> CREATOR = new Parcelable.Creator<POI>() {
+    //        @Override
+    //        public POI createFromParcel(Parcel in) {
+    //            POI poi = new POI(in.readInt());
+    //            poi.id = in.readString();
+    //            poi.location = in.readParcelable(GeoPoint.class.getClassLoader());
+    //            poi.category = in.readString();
+    //            poi.type = in.readString();
+    //            poi.description = in.readString();
+    //            poi.thumbnailPath = in.readString();
+    //            poi.thumbnail = in.readParcelable(Bitmap.class.getClassLoader());
+    //            poi.url = in.readString();
+    //            poi.rank = in.readInt();
+    //            poi.mThumbnailLoadingFailures = in.readInt();
+    //            return poi;
+    //        }
+    //
+    //        @Override
+    //        public POI[] newArray(int size) {
+    //            return new POI[size];
+    //        }
+    //    };
+
+    //    private POI(Parcel in) {
+    //        serviceId = in.readInt();
+    //        id = in.readLong();
+    //        location = in.readParcelable(GeoPoint.class.getClassLoader());
+    //        category = in.readString();
+    //        type = in.readString();
+    //        description = in.readString();
+    //        thumbnailPath = in.readString();
+    //        thumbnail = in.readParcelable(Bitmap.class.getClassLoader());
+    //        url = in.readString();
+    //        rank = in.readInt();
+    //        mThumbnailLoadingFailures = in.readInt();
+    //    }
+}
diff --git a/vtm-app/src/org/osmdroid/location/POIProvider.java b/vtm-app/src/org/osmdroid/location/POIProvider.java
new file mode 100644
index 00000000..11c01446
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/POIProvider.java
@@ -0,0 +1,10 @@
+package org.osmdroid.location;
+
+import org.oscim.core.BoundingBox;
+
+import java.util.List;
+
+public interface POIProvider {
+
+    public List<POI> getPOIInside(BoundingBox boundingBox, String query, int maxResults);
+}
diff --git a/vtm-app/src/org/osmdroid/location/PicasaPOIProvider.java b/vtm-app/src/org/osmdroid/location/PicasaPOIProvider.java
new file mode 100644
index 00000000..9552e2d3
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/location/PicasaPOIProvider.java
@@ -0,0 +1,161 @@
+package org.osmdroid.location;
+
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.utils.HttpConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * POI Provider using Picasa service.
+ *
+ * @author M.Kergall
+ * @see "https://developers.google.com/picasa-web/docs/2.0/reference"
+ */
+public class PicasaPOIProvider implements POIProvider {
+
+    final static Logger log = LoggerFactory.getLogger(PicasaPOIProvider.class);
+
+    String mAccessToken;
+
+    /**
+     * @param accessToken the account to give to the service. Null for public access.
+     * @see "https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol#CreatingAccount"
+     */
+    public PicasaPOIProvider(String accessToken) {
+        mAccessToken = accessToken;
+    }
+
+    @SuppressWarnings("deprecation")
+    private String getUrlInside(BoundingBox boundingBox, int maxResults, String query) {
+        StringBuffer url = new StringBuffer("http://picasaweb.google.com/data/feed/api/all?");
+        url.append("bbox=" + boundingBox.getMinLongitude());
+        url.append("," + boundingBox.getMinLatitude());
+        url.append("," + boundingBox.getMaxLongitude());
+        url.append("," + boundingBox.getMaxLatitude());
+        url.append("&max-results=" + maxResults);
+        url.append("&thumbsize=64c"); //thumbnail size: 64, cropped.
+        url.append("&fields=openSearch:totalResults,entry(summary,media:group/media:thumbnail,media:group/media:title,gphoto:*,georss:where,link)");
+        if (query != null)
+            url.append("&q=" + URLEncoder.encode(query));
+        if (mAccessToken != null) {
+            //TODO: warning: not tested...
+            url.append("&access_token=" + mAccessToken);
+        }
+        return url.toString();
+    }
+
+    public ArrayList<POI> getThem(String fullUrl) {
+        log.debug("PicasaPOIProvider:get:" + fullUrl);
+        HttpConnection connection = new HttpConnection();
+        connection.doGet(fullUrl);
+        InputStream stream = connection.getStream();
+        if (stream == null) {
+            return null;
+        }
+        PicasaXMLHandler handler = new PicasaXMLHandler();
+        try {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            parser.getXMLReader().setFeature("http://xml.org/sax/features/namespaces", false);
+            parser.getXMLReader()
+                    .setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+            parser.parse(stream, handler);
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        } catch (SAXException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        connection.close();
+        if (handler.mPOIs != null)
+            log.debug("done:" + handler.mPOIs.size() + " got on a total of:"
+                    + handler.mTotalResults);
+        return handler.mPOIs;
+    }
+
+    /**
+     * @param boundingBox ...
+     * @param maxResults  ...
+     * @param query       - optional - full-text query string. Searches the title,
+     *                    caption and tags for the specified string value.
+     * @return list of POI, Picasa photos inside the bounding box. Null if
+     * technical issue.
+     */
+    public List<POI> getPOIInside(BoundingBox boundingBox, String query, int maxResults) {
+        String url = getUrlInside(boundingBox, maxResults, query);
+        return getThem(url);
+    }
+}
+
+class PicasaXMLHandler extends DefaultHandler {
+
+    private String mString;
+    double mLat, mLng;
+    POI mPOI;
+    ArrayList<POI> mPOIs;
+    int mTotalResults;
+
+    public PicasaXMLHandler() {
+        mPOIs = new ArrayList<POI>();
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName,
+                             Attributes attributes) {
+        if (qName.equals("entry")) {
+            mPOI = new POI(POI.POI_SERVICE_PICASA);
+        } else if (qName.equals("media:thumbnail")) {
+            mPOI.thumbnailPath = attributes.getValue("url");
+        } else if (qName.equals("link")) {
+            String rel = attributes.getValue("rel");
+            if ("http://schemas.google.com/photos/2007#canonical".equals(rel)) {
+                mPOI.url = attributes.getValue("href");
+            }
+        }
+        mString = new String();
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) {
+        String chars = new String(ch, start, length);
+        mString = mString.concat(chars);
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) {
+        if (qName.equals("gml:pos")) {
+            String[] coords = mString.split(" ");
+            mLat = Double.parseDouble(coords[0]);
+            mLng = Double.parseDouble(coords[1]);
+        } else if (qName.equals("gphoto:id")) {
+            mPOI.id = mString;
+        } else if (qName.equals("media:title")) {
+            mPOI.type = mString;
+        } else if (qName.equals("summary")) {
+            mPOI.description = mString;
+        } else if (qName.equals("gphoto:albumtitle")) {
+            mPOI.category = mString;
+        } else if (qName.equals("entry")) {
+            mPOI.location = new GeoPoint(mLat, mLng);
+            mPOIs.add(mPOI);
+            mPOI = null;
+        } else if (qName.equals("openSearch:totalResults")) {
+            mTotalResults = Integer.parseInt(mString);
+        }
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/overlays/DefaultInfoWindow.java b/vtm-app/src/org/osmdroid/overlays/DefaultInfoWindow.java
new file mode 100644
index 00000000..750ff184
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/overlays/DefaultInfoWindow.java
@@ -0,0 +1,99 @@
+package org.osmdroid.overlays;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.oscim.android.MapView;
+import org.oscim.app.App;
+import org.osmdroid.utils.BonusPackHelper;
+
+/**
+ * Default implementation of InfoWindow. It handles a text and a description. It
+ * also handles optionally a sub-description and an image. Clicking on the
+ * bubble will close it.
+ *
+ * @author M.Kergall
+ */
+public class DefaultInfoWindow extends InfoWindow {
+
+    // resource ids
+    private static int mTitleId = 0, mDescriptionId = 0, mSubDescriptionId = 0, mImageId = 0;
+
+    private static void setResIds(Context context) {
+        // get application package name
+        String packageName = context.getPackageName();
+        Resources res = context.getResources();
+
+        mTitleId = res.getIdentifier("id/bubble_title", null, packageName);
+        mDescriptionId = res.getIdentifier("id/bubble_description", null, packageName);
+        mSubDescriptionId = res.getIdentifier("id/bubble_subdescription", null, packageName);
+        mImageId = res.getIdentifier("id/bubble_image", null, packageName);
+
+        if (mTitleId == 0 || mDescriptionId == 0) {
+            Log.e(BonusPackHelper.LOG_TAG, "DefaultInfoWindow: unable to get res ids in "
+                    + packageName);
+        }
+    }
+
+    public DefaultInfoWindow(int layoutResId, MapView mapView) {
+        super(layoutResId, mapView);
+
+        if (mTitleId == 0)
+            setResIds(App.activity);
+
+        // default behaviour: close it when clicking on the bubble:
+        mView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                close();
+            }
+        });
+    }
+
+    @Override
+    public void onOpen(ExtendedMarkerItem item) {
+        String title = item.getTitle();
+        if (title == null)
+            title = "";
+
+        ((TextView) mView.findViewById(mTitleId)).setText(title);
+
+        String snippet = item.getDescription();
+        if (snippet == null)
+            snippet = "";
+
+        ((TextView) mView.findViewById(mDescriptionId)).setText(snippet);
+
+        // handle sub-description, hidding or showing the text view:
+        TextView subDescText = (TextView) mView.findViewById(mSubDescriptionId);
+        String subDesc = item.getSubDescription();
+        if (subDesc != null && !("".equals(subDesc))) {
+            subDescText.setText(subDesc);
+            subDescText.setVisibility(View.VISIBLE);
+        } else {
+            subDescText.setVisibility(View.GONE);
+        }
+
+        // handle image
+        ImageView imageView = (ImageView) mView.findViewById(mImageId);
+        Drawable image = item.getImage();
+        if (image != null) {
+            // or setBackgroundDrawable(image)?
+            imageView.setImageDrawable(image);
+            imageView.setVisibility(View.VISIBLE);
+        } else
+            imageView.setVisibility(View.GONE);
+
+    }
+
+    @Override
+    public void onClose() {
+        // by default, do nothing
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/overlays/ExtendedMarkerItem.java b/vtm-app/src/org/osmdroid/overlays/ExtendedMarkerItem.java
new file mode 100644
index 00000000..fcde0141
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/overlays/ExtendedMarkerItem.java
@@ -0,0 +1,123 @@
+package org.osmdroid.overlays;
+
+import android.graphics.drawable.Drawable;
+
+import org.oscim.core.GeoPoint;
+import org.oscim.layers.marker.MarkerItem;
+import org.oscim.map.Map;
+
+/**
+ * An OverlayItem to use in ItemizedOverlayWithBubble<br>
+ * - more complete: can contain an image and a sub-description that will be
+ * displayed in the bubble, <br>
+ * - and flexible: attributes are modifiable<br>
+ * Known Issues:<br>
+ * - Bubble offset is not perfect on h&xhdpi resolutions, due to an osmdroid
+ * issue on marker drawing<br>
+ * - Bubble offset is at 0 when using the default marker => set the marker on
+ * each item!<br>
+ *
+ * @author M.Kergall
+ * @see ItemizedOverlayWithBubble
+ */
+public class ExtendedMarkerItem extends MarkerItem {
+
+    // now, they are modifiable
+    private String mTitle, mDescription;
+    // now, they are modifiable
+    // a third field that can be displayed in
+    // the infowindow, on a third line
+    // that will be shown in the infowindow.
+    //unfortunately, this is not so simple...
+    private String mSubDescription;
+    private Drawable mImage;
+    private Object mRelatedObject; // reference to an object (of any kind)
+    // linked to this item.
+
+    public ExtendedMarkerItem(String aTitle, String aDescription, GeoPoint aGeoPoint) {
+        super(aTitle, aDescription, aGeoPoint);
+        mTitle = aTitle;
+        mDescription = aDescription;
+        mSubDescription = null;
+        mImage = null;
+        mRelatedObject = null;
+    }
+
+    public void setTitle(String aTitle) {
+        mTitle = aTitle;
+    }
+
+    public void setDescription(String aDescription) {
+        mDescription = aDescription;
+    }
+
+    public void setSubDescription(String aSubDescription) {
+        mSubDescription = aSubDescription;
+    }
+
+    public void setImage(Drawable anImage) {
+        mImage = anImage;
+    }
+
+    public void setRelatedObject(Object o) {
+        mRelatedObject = o;
+    }
+
+    @Override
+    public String getTitle() {
+        return mTitle;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public String getSubDescription() {
+        return mSubDescription;
+    }
+
+    public Drawable getImage() {
+        return mImage;
+    }
+
+    public Object getRelatedObject() {
+        return mRelatedObject;
+    }
+
+    /**
+     * Populates this bubble with all item info:
+     * <ul>
+     * title and description in any case,
+     * </ul>
+     * <ul>
+     * image and sub-description if any.
+     * </ul>
+     * and centers the map on the item. <br>
+     *
+     * @param bubble ...
+     * @param map    ...
+     */
+    public void showBubble(InfoWindow bubble, Map map) {
+        // offset the bubble to be top-centered on the marker:
+        //        Drawable marker = getMarker(0 /* OverlayItem.ITEM_STATE_FOCUSED_MASK */);
+        //        int markerWidth = 0, markerHeight = 0;
+        //        if (marker != null) {
+        //            markerWidth = marker.getIntrinsicWidth();
+        //            markerHeight = marker.getIntrinsicHeight();
+        //        } // else... we don't have the default marker size => don't user default
+        //            // markers!!!
+        //        Point markerH = getHotspot(getMarkerHotspot(), markerWidth, markerHeight);
+        //        Point bubbleH = getHotspot(HotspotPlace.TOP_CENTER, markerWidth, markerHeight);
+        //        bubbleH.offset(-markerH.x, -markerH.y);
+        //
+        //        bubble.open(this, bubbleH.x, bubbleH.y);
+        //        OverlayMarker marker = getMarker();
+        //        PointF hotspot = marker.getHotspot();
+        //        Bitmap b = marker.getBitmap();
+
+        //bubble.open(this, (int)(-b.getWidth() * hotspot.x), (int)(-b.getHeight()));
+        //bubble.open(this, 0, (int)(b.getHeight()));
+
+        bubble.open(this, 0, 0);
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/overlays/InfoWindow.java b/vtm-app/src/org/osmdroid/overlays/InfoWindow.java
new file mode 100644
index 00000000..9592b8d9
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/overlays/InfoWindow.java
@@ -0,0 +1,135 @@
+package org.osmdroid.overlays;
+
+// TODO composite view as texture overlay and only allow one bubble at a time.
+
+import android.content.Context;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.RelativeLayout;
+
+import org.oscim.android.MapView;
+
+/**
+ * View that can be displayed on an OSMDroid map, associated to a GeoPoint.
+ * Typical usage: cartoon-like bubbles displayed when clicking an overlay item.
+ * It mimics the InfoWindow class of Google Maps JavaScript API V3. Main
+ * differences are:
+ * <ul>
+ * <li>Structure and content of the view is let to the responsibility of the
+ * caller.</li>
+ * <li>The same InfoWindow can be associated to many items.</li>
+ * </ul>
+ * Known issues:
+ * <ul>
+ * <li>It disappears when zooming in/out (osmdroid issue #259 on osmdroid 3.0.8,
+ * should be fixed in next version).</li>
+ * <li>The window is displayed "above" the marker, so the queue of the bubble
+ * can hide the marker.</li>
+ * </ul>
+ * This is an abstract class.
+ *
+ * @author M.Kergall
+ * @see DefaultInfoWindow
+ */
+public abstract class InfoWindow {
+
+    protected View mView;
+    protected boolean mIsVisible = false;
+    protected RelativeLayout mLayout;
+    private android.widget.RelativeLayout.LayoutParams mLayoutPos;
+
+    private MapView mMap;
+
+    /**
+     * @param layoutResId the id of the view resource.
+     * @param mapView     the mapview on which is hooked the view
+     */
+    public InfoWindow(int layoutResId, MapView mapView) {
+        ViewGroup parent = (ViewGroup) mapView.getParent();
+        Context context = mapView.getContext();
+        LayoutInflater inflater = (LayoutInflater) context
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        mView = inflater.inflate(layoutResId, parent, false);
+
+        RelativeLayout.LayoutParams rlp =
+                new RelativeLayout.LayoutParams(
+                        android.view.ViewGroup.LayoutParams.MATCH_PARENT,
+                        android.view.ViewGroup.LayoutParams.MATCH_PARENT);
+        mLayout = new RelativeLayout(context);
+        mLayout.setWillNotDraw(true);
+        mLayout.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+        mLayout.setLayoutParams(rlp);
+        mLayoutPos = rlp;
+        mView.setDrawingCacheEnabled(true);
+        mLayout.addView(mView);
+
+        mIsVisible = false;
+        mLayout.setVisibility(View.GONE);
+        mMap = mapView;
+
+        parent.addView(mLayout);
+    }
+
+    /**
+     * Returns the Android view. This allows to set its content.
+     *
+     * @return the Android view
+     */
+    public View getView() {
+        return (mView);
+    }
+
+    private int mHeight;
+
+    /**
+     * open the window at the specified position.
+     *
+     * @param item    the item on which is hooked the view
+     * @param offsetX (&offsetY) the offset of the view to the position, in pixels.
+     *                This allows to offset the view from the marker position.
+     * @param offsetY ...
+     */
+    public void open(ExtendedMarkerItem item, int offsetX, int offsetY) {
+
+        onOpen(item);
+        close();
+
+        mView.buildDrawingCache();
+
+        mHeight = mMap.getHeight();
+        mLayout.setVisibility(View.VISIBLE);
+        mIsVisible = true;
+
+    }
+
+    public void position(int x, int y) {
+        RelativeLayout.LayoutParams rlp = mLayoutPos;
+        rlp.leftMargin = x;
+        rlp.rightMargin = -x;
+        rlp.topMargin = y;
+        rlp.bottomMargin = mHeight / 2 - y;
+        mLayout.setLayoutParams(rlp);
+        mLayout.requestLayout();
+    }
+
+    public void close() {
+
+        if (mIsVisible) {
+            mIsVisible = false;
+            mLayout.setVisibility(View.GONE);
+            onClose();
+        }
+    }
+
+    public boolean isOpen() {
+        return mIsVisible;
+    }
+
+    // Abstract methods to implement:
+    public abstract void onOpen(ExtendedMarkerItem item);
+
+    public abstract void onClose();
+
+}
diff --git a/vtm-app/src/org/osmdroid/overlays/ItemizedOverlayWithBubble.java b/vtm-app/src/org/osmdroid/overlays/ItemizedOverlayWithBubble.java
new file mode 100644
index 00000000..2a68ab4f
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/overlays/ItemizedOverlayWithBubble.java
@@ -0,0 +1,195 @@
+package org.osmdroid.overlays;
+
+import android.content.Context;
+import android.util.Log;
+
+import org.oscim.app.App;
+import org.oscim.core.GeoPoint;
+import org.oscim.core.MapPosition;
+import org.oscim.core.Point;
+import org.oscim.event.Event;
+import org.oscim.event.MotionEvent;
+import org.oscim.layers.marker.ItemizedLayer;
+import org.oscim.layers.marker.MarkerItem;
+import org.oscim.layers.marker.MarkerSymbol;
+import org.oscim.map.Map;
+import org.osmdroid.utils.BonusPackHelper;
+
+import java.util.List;
+
+/**
+ * An itemized overlay with an InfoWindow or "bubble" which opens when the user
+ * taps on an overlay item, and displays item attributes. <br>
+ * Items must be ExtendedMarkerItem. <br>
+ *
+ * @param <Item> ...
+ * @author M.Kergall
+ * @see ExtendedMarkerItem
+ * @see InfoWindow
+ */
+public class ItemizedOverlayWithBubble<Item extends MarkerItem> extends
+        ItemizedLayer<Item> implements
+        ItemizedLayer.OnItemGestureListener<Item>, Map.UpdateListener {
+
+    /* only one for all items of this overlay => one at a time */
+    protected InfoWindow mBubble;
+
+    /* the item currently showing the bubble. Null if none. */
+    protected MarkerItem mItemWithBubble;
+
+    static int layoutResId = 0;
+
+    public ItemizedOverlayWithBubble(Map map, Context context,
+                                     MarkerSymbol marker, List<Item> list, InfoWindow bubble) {
+        super(map, list, marker, null);
+
+        if (bubble != null) {
+            mBubble = bubble;
+        } else {
+            // build default bubble:
+            String packageName = context.getPackageName();
+            if (layoutResId == 0) {
+                layoutResId = context.getResources().getIdentifier(
+                        "layout/bonuspack_bubble",
+                        null,
+                        packageName);
+                if (layoutResId == 0)
+                    Log.e(BonusPackHelper.LOG_TAG,
+                            "ItemizedOverlayWithBubble: layout/bonuspack_bubble not found in "
+                                    + packageName);
+            }
+            mBubble = new DefaultInfoWindow(layoutResId, App.view);
+        }
+
+        mItemWithBubble = null;
+        mOnItemGestureListener = this;
+    }
+
+    public ItemizedOverlayWithBubble(Map map, Context context,
+                                     MarkerSymbol marker, List<Item> aList) {
+        this(map, context, marker, aList, null);
+    }
+
+    @Override
+    public boolean onItemLongPress(int index, MarkerItem item) {
+        if (mBubble.isOpen())
+            hideBubble();
+        else
+            showBubble(index);
+        return false;
+    }
+
+    @Override
+    public boolean onItemSingleTapUp(int index, MarkerItem item) {
+        showBubble(index);
+
+        return true;
+    }
+
+    private final Point mTmpPoint = new Point();
+
+    @Override
+    protected boolean activateSelectedItems(MotionEvent event, ActiveItem task) {
+        boolean hit = super.activateSelectedItems(event, task);
+
+        if (!hit)
+            hideBubble();
+
+        return hit;
+    }
+
+    @Override
+    public void onMapEvent(Event e, MapPosition mapPosition) {
+        if (mBubble.isOpen()) {
+            GeoPoint gp = mItemWithBubble.getPoint();
+
+            Point p = mTmpPoint;
+            mMap.viewport().toScreenPoint(gp, p);
+
+            mBubble.position((int) p.x, (int) p.y);
+        }
+    }
+
+    void showBubble(int index) {
+        showBubbleOnItem(index);
+    }
+
+    /**
+     * Opens the bubble on the item. For each ItemizedOverlay, only one bubble
+     * is opened at a time. If you want more bubbles opened simultaneously, use
+     * many ItemizedOverlays.
+     *
+     * @param index of the overlay item to show
+     */
+    @SuppressWarnings("unchecked")
+    public void showBubbleOnItem(int index) {
+        ExtendedMarkerItem item = (ExtendedMarkerItem) (mItemList.get(index));
+        mItemWithBubble = item;
+        if (item != null) {
+            item.showBubble(mBubble, (Map) mMap);
+
+            mMap.animator().animateTo(item.geoPoint);
+
+            mMap.updateMap(true);
+            setFocus((Item) item);
+        }
+    }
+
+    /**
+     * Close the bubble (if it's opened).
+     */
+    public void hideBubble() {
+        mBubble.close();
+        mItemWithBubble = null;
+    }
+
+    // @Override
+    // public boolean onSingleTapUp(final MotionEvent event) {
+    // boolean handled = super.onSingleTapUp(event);
+    // if (!handled)
+    // hideBubble();
+    // return handled;
+    // }
+    //
+    // @Override
+    // protected boolean onSingleTapUpHelper(final int index, final Item item) {
+    // showBubbleOnItem(index);
+    // return true;
+    // }
+
+    /**
+     * @return the item currenty showing the bubble, or null if none.
+     */
+    public MarkerItem getBubbledItem() {
+        if (mBubble.isOpen())
+            return mItemWithBubble;
+
+        return null;
+    }
+
+    /**
+     * @return the index of the item currenty showing the bubble, or -1 if none.
+     */
+    public int getBubbledItemId() {
+        MarkerItem item = getBubbledItem();
+        if (item == null)
+            return -1;
+
+        return mItemList.indexOf(item);
+    }
+
+    @Override
+    public boolean removeItem(final Item item) {
+        boolean result = super.removeItem(item);
+        if (mItemWithBubble == item) {
+            hideBubble();
+        }
+        return result;
+    }
+
+    @Override
+    public void removeAllItems() {
+        super.removeAllItems();
+        hideBubble();
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/overlays/MapEventsReceiver.java b/vtm-app/src/org/osmdroid/overlays/MapEventsReceiver.java
new file mode 100644
index 00000000..d4381c33
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/overlays/MapEventsReceiver.java
@@ -0,0 +1,34 @@
+package org.osmdroid.overlays;
+
+import org.oscim.core.GeoPoint;
+
+/**
+ * Interface for objects that need to handle map events thrown by a
+ * MapEventsOverlay.
+ *
+ * @author M.Kergall
+ */
+public interface MapEventsReceiver {
+
+    /**
+     * @param p the position where the event occurred.
+     * @return true if the event has been "consumed" and should not be handled
+     * by other objects.
+     */
+    boolean singleTapUpHelper(GeoPoint p);
+
+    /**
+     * @param p the position where the event occurred.
+     * @return true if the event has been "consumed" and should not be handled
+     * by other objects.
+     */
+    boolean longPressHelper(GeoPoint p);
+
+    /**
+     * @param p1 p2
+     *           the position where the event occurred for 2 finger.
+     * @return true if the event has been "consumed" and should not be handled
+     * by other objects.
+     */
+    boolean longPressHelper(GeoPoint p1, GeoPoint p2);
+}
diff --git a/vtm-app/src/org/osmdroid/routing/Route.java b/vtm-app/src/org/osmdroid/routing/Route.java
new file mode 100644
index 00000000..eab226cc
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/routing/Route.java
@@ -0,0 +1,255 @@
+package org.osmdroid.routing;
+
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.routing.provider.GoogleRouteProvider;
+import org.osmdroid.routing.provider.MapQuestRouteProvider;
+import org.osmdroid.routing.provider.OSRMRouteProvider;
+import org.osmdroid.utils.DouglasPeuckerReducer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * describes the way to go from a position to an other. Normally returned by a
+ * call to a Directions API (from MapQuest, GoogleMaps or other)
+ *
+ * @author M.Kergall
+ * @see MapQuestRouteProvider
+ * @see GoogleRouteProvider
+ * @see OSRMRouteProvider
+ */
+public class Route {
+    //final static Logger log = LoggerFactory.getLogger(Route.class);
+
+    /**
+     * @see #STATUS_INVALID STATUS_INVALID
+     * @see #STATUS_OK STATUS_OK
+     * @see #STATUS_DEFAULT STATUS_DEFAULT
+     */
+    public int status;
+
+    /**
+     * length of the whole route in km.
+     */
+    public double length;
+    /**
+     * duration of the whole trip in sec.
+     */
+    public double duration;
+    public List<RouteNode> nodes;
+    /** */
+    /**
+     * there is one leg between each waypoint
+     */
+    public List<RouteLeg> legs;
+    /**
+     * full shape: polyline, as an array of GeoPoints
+     */
+    public List<GeoPoint> routeHigh;
+    /**
+     * the same, in low resolution (less points)
+     */
+    private List<GeoPoint> routeLow;
+    /**
+     * route bounding box
+     */
+    public BoundingBox boundingBox;
+
+    /**
+     * STATUS_INVALID = route not built
+     */
+    public static final int STATUS_INVALID = 0;
+    /**
+     * STATUS_OK = route properly retrieved and built
+     */
+    public static final int STATUS_OK = 1;
+    /**
+     * STATUS_DEFAULT = any issue (technical issue, or no possible route) led to
+     * build a default route
+     */
+    public static final int STATUS_DEFAULT = 2;
+
+    private void init() {
+        status = STATUS_INVALID;
+        length = 0.0;
+        duration = 0.0;
+        nodes = new ArrayList<RouteNode>();
+        routeHigh = new ArrayList<GeoPoint>();
+        routeLow = null;
+        legs = new ArrayList<RouteLeg>();
+        boundingBox = null;
+    }
+
+    public Route() {
+        init();
+    }
+
+    /**
+     * default constructor when normal loading failed: the route shape only
+     * contains the waypoints; All distances and times are at 0; there is no
+     * node; status equals DEFAULT.
+     *
+     * @param waypoints ...
+     */
+    public Route(List<GeoPoint> waypoints) {
+        init();
+        int n = waypoints.size();
+        for (int i = 0; i < n; i++) {
+            GeoPoint p = waypoints.get(i);
+            routeHigh.add(p);
+        }
+        for (int i = 0; i < n - 1; i++) {
+            RouteLeg leg = new RouteLeg(/* i, i+1, mLinks */);
+            legs.add(leg);
+        }
+        boundingBox = BoundingBox.fromGeoPoints(routeHigh);
+        status = STATUS_DEFAULT;
+    }
+
+    /**
+     * @return the route shape in "low resolution" = simplified by around 10
+     * factor.
+     */
+    public List<GeoPoint> getRouteLow() {
+        if (routeLow == null) {
+            // Simplify the route (divide number of points by around 10):
+            //int n = routeHigh.size();
+            routeLow = DouglasPeuckerReducer.reduceWithTolerance(routeHigh, 1500.0);
+            //log.debug("route reduced from " + n + " to " + routeLow.size()
+            //        + " points");
+        }
+        return routeLow;
+    }
+
+    public void setRouteLow(ArrayList<GeoPoint> route) {
+        routeLow = route;
+    }
+
+    /**
+     * @param pLength   in km
+     * @param pDuration in sec
+     * @return a human-readable length&duration text.
+     */
+    public String getLengthDurationText(double pLength, double pDuration) {
+        String result;
+        if (pLength >= 100.0) {
+            result = (int) (pLength) + " km, ";
+        } else if (pLength >= 1.0) {
+            result = Math.round(pLength * 10) / 10.0 + " km, ";
+        } else {
+            result = (int) (pLength * 1000) + " m, ";
+        }
+        int totalSeconds = (int) pDuration;
+        int hours = totalSeconds / 3600;
+        int minutes = (totalSeconds / 60) - (hours * 60);
+        int seconds = (totalSeconds % 60);
+        if (hours != 0) {
+            result += hours + " h ";
+        }
+        if (minutes != 0) {
+            result += minutes + " min";
+        }
+        if (hours == 0 && minutes == 0) {
+            result += seconds + " s";
+        }
+        return result;
+    }
+
+    /**
+     * @param leg leg index, starting from 0. -1 for the whole route
+     * @return length and duration of the whole route, or of a leg of the route,
+     * as a String, in a readable format.
+     */
+    public String getLengthDurationText(int leg) {
+        double len = (leg == -1 ? this.length : legs.get(leg).length);
+        double dur = (leg == -1 ? this.duration : legs.get(leg).duration);
+        return getLengthDurationText(len, dur);
+    }
+
+    protected double distanceLLSquared(GeoPoint p1, GeoPoint p2) {
+        double deltaLat = p2.latitudeE6 - p1.latitudeE6;
+        double deltaLon = p2.longitudeE6 - p1.longitudeE6;
+        return (deltaLat * deltaLat + deltaLon * deltaLon);
+    }
+
+    /**
+     * As MapQuest and OSRM doesn't provide legs information, we have to rebuild
+     * it, using the waypoints and the route nodes. <br>
+     * Note that MapQuest legs fit well with waypoints, as there is a
+     * "dedicated" node for each waypoint. But OSRM legs are not precise, as
+     * there is no node "dedicated" to waypoints.
+     *
+     * @param waypoints ...
+     */
+    public void buildLegs(List<GeoPoint> waypoints) {
+        legs = new ArrayList<RouteLeg>();
+        int firstNodeIndex = 0;
+        // For all intermediate waypoints, search the node closest to the
+        // waypoint
+        int w = waypoints.size();
+        int n = nodes.size();
+        for (int i = 1; i < w - 1; i++) {
+            GeoPoint waypoint = waypoints.get(i);
+            double distanceMin = -1.0;
+            int nodeIndexMin = -1;
+            for (int j = firstNodeIndex; j < n; j++) {
+                GeoPoint routePoint = nodes.get(j).location;
+                double dSquared = distanceLLSquared(routePoint, waypoint);
+                if (nodeIndexMin == -1 || dSquared < distanceMin) {
+                    distanceMin = dSquared;
+                    nodeIndexMin = j;
+                }
+            }
+            // Build the leg as ending with this closest node:
+            RouteLeg leg = new RouteLeg(firstNodeIndex, nodeIndexMin, nodes);
+            legs.add(leg);
+            firstNodeIndex = nodeIndexMin + 1; // restart next leg from end
+        }
+        // Build last leg ending with last node:
+        RouteLeg lastLeg = new RouteLeg(firstNodeIndex, n - 1, nodes);
+        legs.add(lastLeg);
+    }
+
+    // --- Parcelable implementation
+
+    //    @Override
+    //    public int describeContents() {
+    //        return 0;
+    //    }
+    //
+    //    @Override
+    //    public void writeToParcel(Parcel out, int flags) {
+    //        out.writeInt(status);
+    //        out.writeDouble(length);
+    //        out.writeDouble(duration);
+    //        out.writeList(nodes);
+    //        out.writeList(legs);
+    //        out.writeList(routeHigh);
+    //        out.writeParcelable(boundingBox, 0);
+    //    }
+    //
+    //    public static final Parcelable.Creator<Route> CREATOR = new Parcelable.Creator<Route>() {
+    //        @Override
+    //        public Route createFromParcel(Parcel source) {
+    //            return new Route(source);
+    //        }
+    //
+    //        @Override
+    //        public Route[] newArray(int size) {
+    //            return new Route[size];
+    //        }
+    //    };
+    //
+    //    @SuppressWarnings("unchecked")
+    //    private Route(Parcel in) {
+    //        status = in.readInt();
+    //        length = in.readDouble();
+    //        duration = in.readDouble();
+    //
+    //        nodes = in.readArrayList(RouteNode.class.getClassLoader());
+    //        legs = in.readArrayList(RouteLeg.class.getClassLoader());
+    //        routeHigh = in.readArrayList(GeoPoint.class.getClassLoader());
+    //        boundingBox = in.readParcelable(BoundingBox.class.getClassLoader());
+    //    }
+}
diff --git a/vtm-app/src/org/osmdroid/routing/RouteLeg.java b/vtm-app/src/org/osmdroid/routing/RouteLeg.java
new file mode 100644
index 00000000..d2f49b26
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/routing/RouteLeg.java
@@ -0,0 +1,85 @@
+package org.osmdroid.routing;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+
+/**
+ * Road Leg is the portion of the route between 2 waypoints (intermediate points
+ * requested)
+ *
+ * @author M.Kergall
+ */
+public class RouteLeg implements Parcelable {
+    //final static Logger log = LoggerFactory.getLogger(RouteLeg.class);
+
+    /**
+     * in km
+     */
+    public double length;
+    /**
+     * in sec
+     */
+    public double duration;
+    /**
+     * starting node of the leg, as index in nodes array
+     */
+    public int startNodeIndex;
+    /**
+     * and ending node
+     */
+    public int endNodeIndex;
+
+    public RouteLeg() {
+        length = duration = 0.0;
+        startNodeIndex = endNodeIndex = 0;
+    }
+
+    public RouteLeg(int startNodeIndex, int endNodeIndex,
+                    List<RouteNode> nodes) {
+        this.startNodeIndex = startNodeIndex;
+        this.endNodeIndex = endNodeIndex;
+        length = duration = 0.0;
+
+        for (int i = startNodeIndex; i <= endNodeIndex; i++) {
+            RouteNode node = nodes.get(i);
+            length += node.length;
+            duration += node.duration;
+        }
+        //log.debug("Leg: " + startNodeIndex + "-" + endNodeIndex
+        //        + ", length=" + length + "km, duration=" + duration + "s");
+    }
+
+    //--- Parcelable implementation
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeDouble(length);
+        out.writeDouble(duration);
+        out.writeInt(startNodeIndex);
+        out.writeInt(endNodeIndex);
+    }
+
+    public static final Parcelable.Creator<RouteLeg> CREATOR = new Parcelable.Creator<RouteLeg>() {
+        @Override
+        public RouteLeg createFromParcel(Parcel in) {
+            RouteLeg rl = new RouteLeg();
+            rl.length = in.readDouble();
+            rl.duration = in.readDouble();
+            rl.startNodeIndex = in.readInt();
+            rl.endNodeIndex = in.readInt();
+            return rl;
+        }
+
+        @Override
+        public RouteLeg[] newArray(int size) {
+            return new RouteLeg[size];
+        }
+    };
+}
diff --git a/vtm-app/src/org/osmdroid/routing/RouteNode.java b/vtm-app/src/org/osmdroid/routing/RouteNode.java
new file mode 100644
index 00000000..a822418b
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/routing/RouteNode.java
@@ -0,0 +1,79 @@
+package org.osmdroid.routing;
+
+import org.oscim.core.GeoPoint;
+
+/**
+ * Route intersection, with instructions to continue.
+ *
+ * @author M.Kergall
+ */
+public class RouteNode {
+    /**
+     * @see <a
+     * href="http://open.mapquestapi.com/guidance/#maneuvertypes">Maneuver
+     * Types</a>
+     */
+    public int maneuverType;
+    /**
+     * textual information on what to do at this intersection
+     */
+    public String instructions;
+    /**
+     * index in route links array - internal use only, for MapQuest directions
+     */
+    public int nextRouteLink;
+    /**
+     * in km to the next node
+     */
+    public double length;
+    /**
+     * in seconds to the next node
+     */
+    public double duration;
+    /**
+     * position of the node
+     */
+    public GeoPoint location;
+
+    public RouteNode() {
+        maneuverType = 0;
+        nextRouteLink = -1;
+        length = duration = 0.0;
+    }
+
+    // --- Parcelable implementation
+
+    //    @Override
+    //    public int describeContents() {
+    //        return 0;
+    //    }
+    //
+    //    @Override
+    //    public void writeToParcel(Parcel out, int flags) {
+    //        out.writeInt(maneuverType);
+    //        out.writeString(instructions);
+    //        out.writeDouble(length);
+    //        out.writeDouble(duration);
+    //        out.writeParcelable(location, 0);
+    //    }
+    //
+    //    public static final Parcelable.Creator<RouteNode> CREATOR = new
+    //            Parcelable.Creator<RouteNode>() {
+    //                @Override
+    //                public RouteNode createFromParcel(Parcel in) {
+    //                    RouteNode rn = new RouteNode();
+    //                    rn.maneuverType = in.readInt();
+    //                    rn.instructions = in.readString();
+    //                    rn.length = in.readDouble();
+    //                    rn.duration = in.readDouble();
+    //                    rn.location = in.readParcelable(GeoPoint.class.getClassLoader());
+    //                    return rn;
+    //                }
+    //
+    //                @Override
+    //                public RouteNode[] newArray(int size) {
+    //                    return new RouteNode[size];
+    //                }
+    //            };
+
+}
diff --git a/vtm-app/src/org/osmdroid/routing/RouteProvider.java b/vtm-app/src/org/osmdroid/routing/RouteProvider.java
new file mode 100644
index 00000000..5a5b1fe6
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/routing/RouteProvider.java
@@ -0,0 +1,67 @@
+package org.osmdroid.routing;
+
+import org.oscim.core.GeoPoint;
+import org.oscim.layers.PathLayer;
+import org.oscim.map.Map;
+import org.osmdroid.routing.provider.GoogleRouteProvider;
+import org.osmdroid.routing.provider.MapQuestRouteProvider;
+import org.osmdroid.routing.provider.OSRMRouteProvider;
+
+import java.util.List;
+
+/**
+ * Generic class to get a route between a start and a destination point, going
+ * through a list of waypoints.
+ *
+ * @author M.Kergall
+ * @see MapQuestRouteProvider
+ * @see GoogleRouteProvider
+ * @see OSRMRouteProvider
+ */
+public abstract class RouteProvider {
+
+    protected String mOptions;
+
+    public abstract Route getRoute(List<GeoPoint> waypoints);
+
+    public RouteProvider() {
+        mOptions = "";
+    }
+
+    /**
+     * Add an option that will be used in the route request. Note that some
+     * options are set in the request in all cases.
+     *
+     * @param requestOption see provider documentation. Just one example:
+     *                      "routeType=bicycle" for MapQuest; "mode=bicycling" for Google.
+     */
+    public void addRequestOption(String requestOption) {
+        mOptions += "&" + requestOption;
+    }
+
+    protected String geoPointAsString(GeoPoint p) {
+        StringBuffer result = new StringBuffer();
+        double d = p.getLatitude();
+        result.append(Double.toString(d));
+        d = p.getLongitude();
+        result.append("," + Double.toString(d));
+        return result.toString();
+    }
+
+    /**
+     * Builds an overlay for the route shape with a default (and nice!) color.
+     *
+     * @return route shape overlay
+     */
+    public static PathLayer buildRouteOverlay(Map map, Route route) {
+        int lineColor = 0x800000FF;
+        float lineWidth = 2.5f;
+
+        PathLayer routeOverlay = new PathLayer(map, lineColor, lineWidth);
+        if (route != null) {
+            routeOverlay.setPoints(route.routeHigh);
+        }
+        return routeOverlay;
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/routing/provider/GoogleRouteProvider.java b/vtm-app/src/org/osmdroid/routing/provider/GoogleRouteProvider.java
new file mode 100644
index 00000000..2870f20c
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/routing/provider/GoogleRouteProvider.java
@@ -0,0 +1,235 @@
+package org.osmdroid.routing.provider;
+
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.routing.Route;
+import org.osmdroid.routing.RouteLeg;
+import org.osmdroid.routing.RouteNode;
+import org.osmdroid.routing.RouteProvider;
+import org.osmdroid.utils.HttpConnection;
+import org.osmdroid.utils.PolylineEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * class to get a route between a start and a destination point, going through a
+ * list of waypoints. <br>
+ * https://developers.google.com/maps/documentation/directions/<br>
+ * Note that displaying a route provided by Google on a non-Google map (like
+ * OSM) is not allowed by Google T&C.
+ *
+ * @author M.Kergall
+ */
+public class GoogleRouteProvider extends RouteProvider {
+
+    final static Logger log = LoggerFactory.getLogger(GoogleRouteProvider.class);
+
+    static final String GOOGLE_DIRECTIONS_SERVICE = "http://maps.googleapis.com/maps/api/directions/xml?";
+
+    /**
+     * Build the URL to Google Directions service returning a route in XML
+     * format
+     *
+     * @param waypoints ...
+     * @return ...
+     */
+    protected String getUrl(List<GeoPoint> waypoints) {
+        StringBuffer urlString = new StringBuffer(GOOGLE_DIRECTIONS_SERVICE);
+        urlString.append("origin=");
+        GeoPoint p = waypoints.get(0);
+        urlString.append(geoPointAsString(p));
+        urlString.append("&destination=");
+        int destinationIndex = waypoints.size() - 1;
+        p = waypoints.get(destinationIndex);
+        urlString.append(geoPointAsString(p));
+
+        for (int i = 1; i < destinationIndex; i++) {
+            if (i == 1)
+                urlString.append("&waypoints=");
+            else
+                urlString.append("%7C"); // the pipe (|), url-encoded
+            p = waypoints.get(i);
+            urlString.append(geoPointAsString(p));
+        }
+        urlString.append("&units=metric&sensor=false");
+        Locale locale = Locale.getDefault();
+        urlString.append("&language=" + locale.getLanguage());
+        urlString.append(mOptions);
+        return urlString.toString();
+    }
+
+    /**
+     * @param waypoints : list of GeoPoints. Must have at least 2 entries, start and
+     *                  end points.
+     * @return the route
+     */
+    @Override
+    public Route getRoute(List<GeoPoint> waypoints) {
+        String url = getUrl(waypoints);
+        log.debug("GoogleRouteManager.getRoute:" + url);
+        Route route = null;
+        HttpConnection connection = new HttpConnection();
+        connection.doGet(url);
+        InputStream stream = connection.getStream();
+        if (stream != null)
+            route = getRouteXML(stream);
+        connection.close();
+        if (route == null || route.routeHigh.size() == 0) {
+            //Create default route:
+            route = new Route(waypoints);
+        } else {
+            //finalize route data update:
+            for (RouteLeg leg : route.legs) {
+                route.duration += leg.duration;
+                route.length += leg.length;
+            }
+            route.status = Route.STATUS_OK;
+        }
+        log.debug("GoogleRouteManager.getRoute - finished");
+        return route;
+    }
+
+    protected Route getRouteXML(InputStream is) {
+        GoogleDirectionsHandler handler = new GoogleDirectionsHandler();
+        try {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            parser.parse(is, handler);
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        } catch (SAXException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return handler.mRoute;
+    }
+
+}
+
+class GoogleDirectionsHandler extends DefaultHandler {
+    Route mRoute;
+    RouteLeg mLeg;
+    RouteNode mNode;
+    boolean isPolyline, isOverviewPolyline, isLeg, isStep, isDuration, isDistance, isBB;
+    int mValue;
+    double mLat, mLng;
+    double mNorth, mWest, mSouth, mEast;
+    private String mString;
+
+    public GoogleDirectionsHandler() {
+        isOverviewPolyline = isBB = isPolyline = isLeg = isStep = isDuration = isDistance = false;
+        mRoute = new Route();
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String name,
+                             Attributes attributes) {
+        if (localName.equals("polyline")) {
+            isPolyline = true;
+        } else if (localName.equals("overview_polyline")) {
+            isOverviewPolyline = true;
+        } else if (localName.equals("leg")) {
+            mLeg = new RouteLeg();
+            isLeg = true;
+        } else if (localName.equals("step")) {
+            mNode = new RouteNode();
+            isStep = true;
+        } else if (localName.equals("duration")) {
+            isDuration = true;
+        } else if (localName.equals("distance")) {
+            isDistance = true;
+        } else if (localName.equals("bounds")) {
+            isBB = true;
+        }
+        mString = new String();
+    }
+
+    /**
+     * Overrides org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
+     */
+    public
+    @Override
+    void characters(char[] ch, int start, int length) {
+        String chars = new String(ch, start, length);
+        mString = mString.concat(chars);
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String name) {
+        if (localName.equals("points")) {
+            if (isPolyline) {
+                //detailed piece of route for the step, to add:
+                ArrayList<GeoPoint> polyLine = PolylineEncoder.decode(mString, 10);
+                mRoute.routeHigh.addAll(polyLine);
+            } else if (isOverviewPolyline) {
+                //low-def polyline for the whole route:
+                mRoute.setRouteLow(PolylineEncoder.decode(mString, 10));
+            }
+        } else if (localName.equals("polyline")) {
+            isPolyline = false;
+        } else if (localName.equals("overview_polyline")) {
+            isOverviewPolyline = false;
+        } else if (localName.equals("value")) {
+            mValue = Integer.parseInt(mString);
+        } else if (localName.equals("duration")) {
+            if (isStep)
+                mNode.duration = mValue;
+            else
+                mLeg.duration = mValue;
+            isDuration = false;
+        } else if (localName.equals("distance")) {
+            if (isStep)
+                mNode.length = mValue / 1000.0;
+            else
+                mLeg.length = mValue / 1000.0;
+            isDistance = false;
+        } else if (localName.equals("html_instructions")) {
+            if (isStep) {
+                mString = mString.replaceAll("<[^>]*>", " "); //remove everything in <...>
+                mString = mString.replaceAll("&nbsp;", " ");
+                mNode.instructions = mString;
+                //log.debug(mString);
+            }
+        } else if (localName.equals("start_location")) {
+            if (isStep)
+                mNode.location = new GeoPoint(mLat, mLng);
+        } else if (localName.equals("step")) {
+            mRoute.nodes.add(mNode);
+            isStep = false;
+        } else if (localName.equals("leg")) {
+            mRoute.legs.add(mLeg);
+            isLeg = false;
+        } else if (localName.equals("lat")) {
+            mLat = Double.parseDouble(mString);
+        } else if (localName.equals("lng")) {
+            mLng = Double.parseDouble(mString);
+        } else if (localName.equals("northeast")) {
+            if (isBB) {
+                mNorth = mLat;
+                mEast = mLng;
+            }
+        } else if (localName.equals("southwest")) {
+            if (isBB) {
+                mSouth = mLat;
+                mWest = mLng;
+            }
+        } else if (localName.equals("bounds")) {
+            mRoute.boundingBox = new BoundingBox(mNorth, mEast, mSouth, mWest);
+            isBB = false;
+        }
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/routing/provider/MapQuestRouteProvider.java b/vtm-app/src/org/osmdroid/routing/provider/MapQuestRouteProvider.java
new file mode 100644
index 00000000..4ff3ad6f
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/routing/provider/MapQuestRouteProvider.java
@@ -0,0 +1,289 @@
+package org.osmdroid.routing.provider;
+
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.routing.Route;
+import org.osmdroid.routing.RouteNode;
+import org.osmdroid.routing.RouteProvider;
+import org.osmdroid.utils.HttpConnection;
+import org.osmdroid.utils.PolylineEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * class to get a route between a start and a destination point, going through a
+ * list of waypoints. It uses MapQuest open, public and free API, based on
+ * OpenStreetMap data. <br>
+ * See http://open.mapquestapi.com/guidance
+ *
+ * @author M.Kergall
+ */
+public class MapQuestRouteProvider extends RouteProvider {
+
+    final static Logger log = LoggerFactory.getLogger(MapQuestRouteProvider.class);
+
+    static final String MAPQUEST_GUIDANCE_SERVICE = "http://open.mapquestapi.com/guidance/v0/route?";
+
+    /**
+     * Build the URL to MapQuest service returning a route in XML format
+     *
+     * @param waypoints : array of waypoints, as [lat, lng], from start point to end
+     *                  point.
+     * @return ...
+     */
+    protected String getUrl(List<GeoPoint> waypoints) {
+        StringBuffer urlString = new StringBuffer(MAPQUEST_GUIDANCE_SERVICE);
+        urlString.append("from=");
+        GeoPoint p = waypoints.get(0);
+        urlString.append(geoPointAsString(p));
+
+        for (int i = 1; i < waypoints.size(); i++) {
+            p = waypoints.get(i);
+            urlString.append("&to=" + geoPointAsString(p));
+        }
+
+        urlString.append("&outFormat=xml");
+        urlString.append("&shapeFormat=cmp"); // encoded polyline, much faster
+
+        urlString.append("&narrativeType=text"); // or "none"
+        // Locale locale = Locale.getDefault();
+        // urlString.append("&locale="+locale.getLanguage()+"_"+locale.getCountry());
+
+        urlString.append("&unit=k&fishbone=false");
+
+        // urlString.append("&generalizeAfter=500" /*+&generalize=2"*/);
+        // 500 points max, 2 meters tolerance
+
+        // Warning: MapQuest Open API doc is sometimes WRONG:
+        // - use unit, not units
+        // - use fishbone, not enableFishbone
+        // - locale (fr_FR, en_US) is supported but not documented.
+        // - generalize and generalizeAfter are not properly implemented
+        urlString.append(mOptions);
+        return urlString.toString();
+    }
+
+    /**
+     * @param waypoints : list of GeoPoints. Must have at least 2 entries, start and
+     *                  end points.
+     * @return the route
+     */
+    @Override
+    public Route getRoute(List<GeoPoint> waypoints) {
+        String url = getUrl(waypoints);
+        log.debug("MapQuestRouteManager.getRoute:" + url);
+        Route route = null;
+        HttpConnection connection = new HttpConnection();
+        connection.doGet(url);
+        InputStream stream = connection.getStream();
+        if (stream != null)
+            route = getRouteXML(stream, waypoints);
+        if (route == null || route.routeHigh.size() == 0) {
+            // Create default route:
+            route = new Route(waypoints);
+        }
+        connection.close();
+        log.debug("MapQuestRouteManager.getRoute - finished");
+        return route;
+    }
+
+    /**
+     * XML implementation
+     *
+     * @param is        : input stream to parse
+     * @param waypoints ...
+     * @return the route ...
+     */
+    protected Route getRouteXML(InputStream is, List<GeoPoint> waypoints) {
+        XMLHandler handler = new XMLHandler();
+        try {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            parser.parse(is, handler);
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        } catch (SAXException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        Route route = handler.mRoute;
+        if (route != null && route.routeHigh.size() > 0) {
+            route.nodes = finalizeNodes(route.nodes, handler.mLinks, route.routeHigh);
+            route.buildLegs(waypoints);
+            route.status = Route.STATUS_OK;
+        }
+        return route;
+    }
+
+    protected List<RouteNode> finalizeNodes(List<RouteNode> mNodes,
+                                            List<RouteLink> mLinks, List<GeoPoint> polyline) {
+        int n = mNodes.size();
+        if (n == 0)
+            return mNodes;
+        ArrayList<RouteNode> newNodes = new ArrayList<RouteNode>(n);
+        RouteNode lastNode = null;
+        for (int i = 1; i < n - 1; i++) { // 1, n-1 => first and last MapQuest
+            // nodes are irrelevant.
+            RouteNode node = mNodes.get(i);
+            RouteLink link = mLinks.get(node.nextRouteLink);
+            if (lastNode != null && (node.instructions == null || node.maneuverType == 0)) {
+                // this node is irrelevant, don't keep it,
+                // but update values of last node:
+                lastNode.length += link.mLength;
+                lastNode.duration += (node.duration + link.mDuration);
+            } else {
+                node.length = link.mLength;
+                node.duration += link.mDuration;
+                int locationIndex = link.mShapeIndex;
+                node.location = polyline.get(locationIndex);
+                newNodes.add(node);
+                lastNode = node;
+            }
+        }
+        // switch to the new array of nodes:
+        return newNodes;
+    }
+}
+
+/**
+ * Route Link is a portion of route between 2 "nodes" or intersections
+ */
+class RouteLink {
+    /**
+     * in km/h
+     */
+    public double mSpeed;
+    /**
+     * in km
+     */
+    public double mLength;
+    /**
+     * in sec
+     */
+    public double mDuration;
+    /**
+     * starting point of the link, as index in initial polyline
+     */
+    public int mShapeIndex;
+}
+
+/**
+ * XMLHandler: class to handle XML generated by MapQuest "guidance" open API.
+ */
+class XMLHandler extends DefaultHandler {
+    public Route mRoute;
+    public ArrayList<RouteLink> mLinks;
+
+    boolean isBB;
+    boolean isGuidanceNodeCollection;
+    private String mString;
+    double mLat, mLng;
+    double mNorth, mWest, mSouth, mEast;
+    RouteLink mLink;
+    RouteNode mNode;
+
+    public XMLHandler() {
+        isBB = isGuidanceNodeCollection = false;
+        mRoute = new Route();
+        mLinks = new ArrayList<RouteLink>();
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String name,
+                             Attributes attributes) {
+        if (localName.equals("boundingBox"))
+            isBB = true;
+        else if (localName.equals("link"))
+            mLink = new RouteLink();
+        else if (localName.equals("node"))
+            mNode = new RouteNode();
+        else if (localName.equals("GuidanceNodeCollection"))
+            isGuidanceNodeCollection = true;
+        mString = new String();
+    }
+
+    /**
+     * Overrides org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
+     */
+    @Override
+    public void characters(char[] ch, int start, int length) {
+        String chars = new String(ch, start, length);
+        mString = mString.concat(chars);
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String name) {
+        if (localName.equals("lat")) {
+            mLat = Double.parseDouble(mString);
+        } else if (localName.equals("lng")) {
+            mLng = Double.parseDouble(mString);
+        } else if (localName.equals("shapePoints")) {
+            mRoute.routeHigh = PolylineEncoder.decode(mString, 10);
+            // log.debug("High="+mRoute.mRouteHigh.size());
+        } else if (localName.equals("generalizedShape")) {
+            mRoute.setRouteLow(PolylineEncoder.decode(mString, 10));
+            // log.debug("Low="+mRoute.mRouteLow.size());
+        } else if (localName.equals("length")) {
+            mLink.mLength = Double.parseDouble(mString);
+        } else if (localName.equals("speed")) {
+            mLink.mSpeed = Double.parseDouble(mString);
+        } else if (localName.equals("shapeIndex")) {
+            mLink.mShapeIndex = Integer.parseInt(mString);
+        } else if (localName.equals("link")) {
+            // End of a link: update route attributes:
+            // GuidanceLinkCollection could in theory contain additional unused
+            // links,
+            // but normally not with fishbone set to false.
+            mLink.mDuration = mLink.mLength / mLink.mSpeed * 3600.0;
+            mLinks.add(mLink);
+            mRoute.length += mLink.mLength;
+            mRoute.duration += mLink.mDuration;
+            mLink = null;
+        } else if (localName.equals("turnCost")) {
+            int turnCost = Integer.parseInt(mString);
+            mNode.duration += turnCost;
+            mRoute.duration += turnCost;
+        } else if (localName.equals("maneuverType")) {
+            mNode.maneuverType = Integer.parseInt(mString);
+        } else if (localName.equals("info")) {
+            if (isGuidanceNodeCollection) {
+                if (mNode.instructions == null)
+                    // this is first "info" value for this node, keep it:
+                    mNode.instructions = mString;
+            }
+        } else if (localName.equals("linkId")) {
+            if (isGuidanceNodeCollection)
+                mNode.nextRouteLink = Integer.parseInt(mString);
+        } else if (localName.equals("node")) {
+            mRoute.nodes.add(mNode);
+            mNode = null;
+        } else if (localName.equals("GuidanceNodeCollection")) {
+            isGuidanceNodeCollection = false;
+        } else if (localName.equals("ul")) {
+            if (isBB) {
+                mNorth = mLat;
+                mWest = mLng;
+            }
+        } else if (localName.equals("lr")) {
+            if (isBB) {
+                mSouth = mLat;
+                mEast = mLng;
+            }
+        } else if (localName.equals("boundingBox")) {
+            mRoute.boundingBox = new BoundingBox(mNorth, mEast, mSouth, mWest);
+            isBB = false;
+        }
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/routing/provider/OSRMRouteProvider.java b/vtm-app/src/org/osmdroid/routing/provider/OSRMRouteProvider.java
new file mode 100644
index 00000000..976325b4
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/routing/provider/OSRMRouteProvider.java
@@ -0,0 +1,294 @@
+package org.osmdroid.routing.provider;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.oscim.core.BoundingBox;
+import org.oscim.core.GeoPoint;
+import org.osmdroid.routing.Route;
+import org.osmdroid.routing.RouteNode;
+import org.osmdroid.routing.RouteProvider;
+import org.osmdroid.utils.BonusPackHelper;
+import org.osmdroid.utils.HttpConnection;
+import org.osmdroid.utils.PolylineEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * get a route between a start and a destination point. It uses OSRM, a free
+ * open source routing service based on OpenSteetMap data. <br>
+ * See https://github.com/DennisOSRM/Project-OSRM/wiki/Server-api<br>
+ * It requests by default the OSRM demo site. Use setService() to request an
+ * other (for instance your own) OSRM service. <br>
+ * TODO: improve internationalization of instructions
+ *
+ * @author M.Kergall
+ */
+public class OSRMRouteProvider extends RouteProvider {
+
+    final static Logger log = LoggerFactory.getLogger(OSRMRouteProvider.class);
+
+    // 1 for 6 digit precision, 10 for 5
+    private final static int ENCODING_PRECISION = 1;
+
+    //static final String OSRM_SERVICE = "http://city.informatik.uni-bremen.de:5000/viaroute?";
+    //static final String OSRM_SERVICE = "http://city.informatik.uni-bremen.de:5001/viaroute?";
+    static final String OSRM_SERVICE = "http://router.project-osrm.org/viaroute?";
+
+    //Note that the result of OSRM is quite close to Cloudmade NavEngine format:
+    //http://developers.cloudmade.com/wiki/navengine/JSON_format
+
+    protected String mServiceUrl;
+    protected String mUserAgent;
+
+    /**
+     * mapping from OSRM directions to MapQuest maneuver IDs:
+     */
+    static final HashMap<String, Integer> MANEUVERS;
+
+    static {
+        MANEUVERS = new HashMap<String, Integer>();
+        MANEUVERS.put("0", Integer.valueOf(0)); //No instruction
+        MANEUVERS.put("1", Integer.valueOf(1)); //Continue
+        MANEUVERS.put("2", Integer.valueOf(6)); //Slight right
+        MANEUVERS.put("3", Integer.valueOf(7)); //Right
+        MANEUVERS.put("4", Integer.valueOf(8)); //Sharp right
+        MANEUVERS.put("5", Integer.valueOf(12)); //U-turn
+        MANEUVERS.put("6", Integer.valueOf(5)); //Sharp left
+        MANEUVERS.put("7", Integer.valueOf(4)); //Left
+        MANEUVERS.put("8", Integer.valueOf(3)); //Slight left
+        MANEUVERS.put("9", Integer.valueOf(24)); //Arrived (at waypoint)
+        //MANEUVERS.put("10", Integer.valueOf(0)); //"Head" => used by OSRM as the start node
+        MANEUVERS.put("11-1", Integer.valueOf(27)); //Round-about, 1st exit
+        MANEUVERS.put("11-2", Integer.valueOf(28)); //2nd exit, etc ...
+        MANEUVERS.put("11-3", Integer.valueOf(29));
+        MANEUVERS.put("11-4", Integer.valueOf(30));
+        MANEUVERS.put("11-5", Integer.valueOf(31));
+        MANEUVERS.put("11-6", Integer.valueOf(32));
+        MANEUVERS.put("11-7", Integer.valueOf(33));
+        MANEUVERS.put("11-8", Integer.valueOf(34)); //Round-about, 8th exit
+        MANEUVERS.put("15", Integer.valueOf(24)); //Arrived
+    }
+
+    //From: Project-OSRM-Web / WebContent / localization / OSRM.Locale.en.js
+    // driving directions
+    // %s: route name
+    // %d: direction => removed
+    // <*>: will only be printed when there actually is a route name
+    static final HashMap<String, HashMap<String, String>> DIRECTIONS;
+
+    static {
+        DIRECTIONS = new HashMap<String, HashMap<String, String>>();
+        HashMap<String, String> directions;
+
+        directions = new HashMap<String, String>();
+        DIRECTIONS.put("en", directions);
+        directions.put("0", "Unknown instruction< on %s>");
+        directions.put("1", "Continue< on %s>");
+        directions.put("2", "Turn slight right< on %s>");
+        directions.put("3", "Turn right< on %s>");
+        directions.put("4", "Turn sharp right< on %s>");
+        directions.put("5", "U-Turn< on %s>");
+        directions.put("6", "Turn sharp left< on %s>");
+        directions.put("7", "Turn left< on %s>");
+        directions.put("8", "Turn slight left< on %s>");
+        directions.put("9", "You have reached a waypoint of your trip");
+        directions.put("10", "<Go on %s>");
+        directions.put("11-1", "Enter roundabout and leave at first exit< on %s>");
+        directions.put("11-2", "Enter roundabout and leave at second exit< on %s>");
+        directions.put("11-3", "Enter roundabout and leave at third exit< on %s>");
+        directions.put("11-4", "Enter roundabout and leave at fourth exit< on %s>");
+        directions.put("11-5", "Enter roundabout and leave at fifth exit< on %s>");
+        directions.put("11-6", "Enter roundabout and leave at sixth exit< on %s>");
+        directions.put("11-7", "Enter roundabout and leave at seventh exit< on %s>");
+        directions.put("11-8", "Enter roundabout and leave at eighth exit< on %s>");
+        directions.put("11-9", "Enter roundabout and leave at nineth exit< on %s>");
+        directions.put("15", "You have reached your destination");
+
+        directions = new HashMap<String, String>();
+        DIRECTIONS.put("fr", directions);
+        directions.put("0", "Instruction inconnue< sur %s>");
+        directions.put("1", "Continuez< sur %s>");
+        directions.put("2", "Tournez légèrement à droite< sur %s>");
+        directions.put("3", "Tournez à droite< sur %s>");
+        directions.put("4", "Tournez fortement à droite< sur %s>");
+        directions.put("5", "Faites demi-tour< sur %s>");
+        directions.put("6", "Tournez fortement à gauche< sur %s>");
+        directions.put("7", "Tournez à gauche< sur %s>");
+        directions.put("8", "Tournez légèrement à gauche< sur %s>");
+        directions.put("9", "Vous êtes arrivé à une étape de votre voyage");
+        directions.put("10", "<Prenez %s>");
+        directions.put("11-1", "Au rond-point, prenez la première sortie< sur %s>");
+        directions.put("11-2", "Au rond-point, prenez la deuxième sortie< sur %s>");
+        directions.put("11-3", "Au rond-point, prenez la troisième sortie< sur %s>");
+        directions.put("11-4", "Au rond-point, prenez la quatrième sortie< sur %s>");
+        directions.put("11-5", "Au rond-point, prenez la cinquième sortie< sur %s>");
+        directions.put("11-6", "Au rond-point, prenez la sixième sortie< sur %s>");
+        directions.put("11-7", "Au rond-point, prenez la septième sortie< sur %s>");
+        directions.put("11-8", "Au rond-point, prenez la huitième sortie< sur %s>");
+        directions.put("11-9", "Au rond-point, prenez la neuvième sortie< sur %s>");
+        directions.put("15", "Vous êtes arrivé");
+
+        directions = new HashMap<String, String>();
+        DIRECTIONS.put("pl", directions);
+        directions.put("0", "Nieznana instrukcja<w %s>");
+        directions.put("1", "Kontynuuj jazdę<na %s>");
+        directions.put("2", "Skręć lekko w prawo<w %s>");
+        directions.put("3", "Skręć w prawo<w %s>");
+        directions.put("4", "Skręć ostro w prawo<w %s>");
+        directions.put("5", "Zawróć<na %s>");
+        directions.put("6", "Skręć ostro w lewo<w %s>");
+        directions.put("7", "Skręć w lewo<w %s>");
+        directions.put("8", "Skręć lekko w lewo<w %s>");
+        directions.put("9", "Dotarłeś do punktu pośredniego");
+        directions.put("10", "<Jedź %s>");
+        directions.put("11-1", "Wjedź na rondo i opuść je pierwszym zjazdem<w %s>");
+        directions.put("11-2", "Wjedź na rondo i opuść je drugim zjazdem<w %s>");
+        directions.put("11-3", "Wjedź na rondo i opuść je trzecim zjazdem<w %s>");
+        directions.put("11-4", "Wjedź na rondo i opuść je czwartym zjazdem<w %s>");
+        directions.put("11-5", "Wjedź na rondo i opuść je piątym zjazdem<w %s>");
+        directions.put("11-6", "Wjedź na rondo i opuść je szóstym zjazdem<w %s>");
+        directions.put("11-7", "Wjedź na rondo i opuść je siódmym zjazdem<w %s>");
+        directions.put("11-8", "Wjedź na rondo i opuść je ósmym zjazdem<w %s>");
+        directions.put("11-9", "Wjedź na rondo i opuść je dziewiątym zjazdem<w %s>");
+        directions.put("15", "Dotarłeś do celu podróży");
+    }
+
+    public OSRMRouteProvider() {
+        super();
+        mServiceUrl = OSRM_SERVICE;
+        mUserAgent = BonusPackHelper.DEFAULT_USER_AGENT; //set user agent to the default one.
+    }
+
+    /**
+     * allows to request on an other site than OSRM demo site
+     *
+     * @param serviceUrl ...
+     */
+    public void setService(String serviceUrl) {
+        mServiceUrl = serviceUrl;
+    }
+
+    /**
+     * allows to send to OSRM service a user agent specific to the app, instead
+     * of the default user agent of OSMBonusPack lib.
+     *
+     * @param userAgent ...
+     */
+    public void setUserAgent(String userAgent) {
+        mUserAgent = userAgent;
+    }
+
+    protected String getUrl(List<GeoPoint> waypoints) {
+        StringBuffer urlString = new StringBuffer(mServiceUrl);
+        for (int i = 0; i < waypoints.size(); i++) {
+            GeoPoint p = waypoints.get(i);
+            urlString.append("&loc=" + geoPointAsString(p));
+        }
+        urlString.append(mOptions);
+        return urlString.toString();
+    }
+
+    @Override
+    public Route getRoute(List<GeoPoint> waypoints) {
+        String url = getUrl(waypoints);
+        log.debug("OSRMRouteManager.getRoute:" + url);
+
+        //String jString = BonusPackHelper.requestStringFromUrl(url);
+        HttpConnection connection = new HttpConnection();
+        connection.setUserAgent(mUserAgent);
+        connection.doGet(url);
+        String jString = connection.getContentAsString();
+        connection.close();
+
+        if (jString == null) {
+            log.error("OSRMRouteManager::getRoute: request failed.");
+            return new Route(waypoints);
+        }
+        Locale l = Locale.getDefault();
+        HashMap<String, String> directions = DIRECTIONS.get(l.getLanguage());
+        if (directions == null)
+            directions = DIRECTIONS.get("en");
+        Route route = new Route();
+        try {
+            JSONObject jObject = new JSONObject(jString);
+            String route_geometry = jObject.getString("route_geometry");
+            route.routeHigh = PolylineEncoder.decode(route_geometry, ENCODING_PRECISION);
+            JSONArray jInstructions = jObject.getJSONArray("route_instructions");
+            int n = jInstructions.length();
+            RouteNode lastNode = null;
+            for (int i = 0; i < n; i++) {
+                JSONArray jInstruction = jInstructions.getJSONArray(i);
+                RouteNode node = new RouteNode();
+                int positionIndex = jInstruction.getInt(3);
+                node.location = route.routeHigh.get(positionIndex);
+                node.length = jInstruction.getInt(2) / 1000.0;
+                node.duration = jInstruction.getInt(4); //Segment duration in seconds.
+                String direction = jInstruction.getString(0);
+                String routeName = jInstruction.getString(1);
+                if (lastNode != null && "1".equals(direction) && "".equals(routeName)) {
+                    //node "Continue" with no route name is useless, don't add it
+                    lastNode.length += node.length;
+                    lastNode.duration += node.duration;
+                } else {
+                    node.maneuverType = getManeuverCode(direction);
+                    node.instructions = buildInstructions(direction, routeName, directions);
+                    //log.debug(direction+"=>"+node.mManeuverType+"; "+node.mInstructions);
+                    route.nodes.add(node);
+                    lastNode = node;
+                }
+            }
+            JSONObject jSummary = jObject.getJSONObject("route_summary");
+            route.length = jSummary.getInt("total_distance") / 1000.0;
+            route.duration = jSummary.getInt("total_time");
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return new Route(waypoints);
+        }
+        if (route.routeHigh.size() == 0) {
+            //Create default route:
+            route = new Route(waypoints);
+        } else {
+            route.buildLegs(waypoints);
+            BoundingBox bb = BoundingBox.fromGeoPoints(route.routeHigh);
+            //Correcting osmdroid bug #359:
+            route.boundingBox = bb;
+            //    new BoundingBox(
+            //    bb.getLatSouthE6(), bb.getLonWestE6(), bb.getLatNorthE6(), bb.getLonEastE6());
+            route.status = Route.STATUS_OK;
+        }
+        log.debug("OSRMRouteManager.getRoute - finished");
+        return route;
+    }
+
+    protected int getManeuverCode(String direction) {
+        Integer code = MANEUVERS.get(direction);
+        if (code != null)
+            return code.intValue();
+
+        return 0;
+    }
+
+    protected String buildInstructions(String direction, String routeName,
+                                       HashMap<String, String> directions) {
+        if (directions == null)
+            return null;
+        direction = directions.get(direction);
+        if (direction == null)
+            return null;
+        String instructions = null;
+        if (routeName.equals(""))
+            //remove "<*>"
+            instructions = direction.replaceFirst("<[^>]*>", "");
+        else {
+            direction = direction.replace('<', ' ');
+            direction = direction.replace('>', ' ');
+            instructions = String.format(direction, routeName);
+        }
+        return instructions;
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/utils/BonusPackHelper.java b/vtm-app/src/org/osmdroid/utils/BonusPackHelper.java
new file mode 100644
index 00000000..1e75e2f6
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/utils/BonusPackHelper.java
@@ -0,0 +1,112 @@
+package org.osmdroid.utils;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Build;
+
+import java.io.FileNotFoundException;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * Useful functions and common constants.
+ *
+ * @author M.Kergall
+ */
+public class BonusPackHelper {
+
+    /**
+     * Log tag.
+     */
+    public static final String LOG_TAG = "BONUSPACK";
+
+    /**
+     * User agent sent to services by default
+     */
+    public static final String DEFAULT_USER_AGENT = "OsmBonusPack/1";
+
+    /**
+     * @return true if the device is the emulator, false if actual device.
+     */
+    public static boolean isEmulator() {
+        //return Build.MANUFACTURER.equals("unknown");
+        return ("google_sdk".equals(Build.PRODUCT) || "sdk".equals(Build.PRODUCT));
+    }
+
+    /**
+     * @param connection ...
+     * @return the whole content of the http request, as a string
+     */
+    private static String readStream(HttpConnection connection) {
+        String result = connection.getContentAsString();
+        return result;
+    }
+
+    /**
+     * sends an http request, and returns the whole content result in a String.
+     *
+     * @param url ...
+     * @return the whole content, or null if any issue.
+     */
+    public static String requestStringFromUrl(String url) {
+        HttpConnection connection = new HttpConnection();
+        connection.doGet(url);
+        String result = readStream(connection);
+        connection.close();
+        return result;
+    }
+
+    /**
+     * Loads a bitmap from a url.
+     *
+     * @param url ...
+     * @return the bitmap, or null if any issue.
+     */
+    public static Bitmap loadBitmap(String url) {
+        Bitmap bitmap = null;
+        try {
+            InputStream is = (InputStream) new URL(url).getContent();
+            bitmap = BitmapFactory.decodeStream(new FlushedInputStream(is));
+            //Alternative providing better handling on loading errors?
+            /* Drawable d = Drawable.createFromStream(new
+             * FlushedInputStream(is), null); if (is != null) is.close(); if (d
+             * != null) bitmap = ((BitmapDrawable)d).getBitmap(); */
+        } catch (FileNotFoundException e) {
+            //log.debug("image not available: " + url);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+        return bitmap;
+    }
+
+    /**
+     * Workaround on Android issue see
+     * http://stackoverflow.com/questions/4601352
+     * /createfromstream-in-android-returning-null-for-certain-url
+     */
+    static class FlushedInputStream extends FilterInputStream {
+        public FlushedInputStream(InputStream inputStream) {
+            super(inputStream);
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            long totalBytesSkipped = 0L;
+            while (totalBytesSkipped < n) {
+                long bytesSkipped = in.skip(n - totalBytesSkipped);
+                if (bytesSkipped == 0L) {
+                    int byteValue = read();
+                    if (byteValue < 0)
+                        break; // we reached EOF
+
+                    bytesSkipped = 1; // we read one byte
+                }
+                totalBytesSkipped += bytesSkipped;
+            }
+            return totalBytesSkipped;
+        }
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/utils/DouglasPeuckerReducer.java b/vtm-app/src/org/osmdroid/utils/DouglasPeuckerReducer.java
new file mode 100644
index 00000000..a991a306
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/utils/DouglasPeuckerReducer.java
@@ -0,0 +1,141 @@
+package org.osmdroid.utils;
+
+import org.oscim.core.GeoPoint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Reduces the number of points in a shape using the Douglas-Peucker algorithm. <br>
+ * From:
+ * http://www.phpriot.com/articles/reducing-map-path-douglas-peucker-algorithm/4<br>
+ * Ported from PHP to Java. "marked" array added to optimize.
+ *
+ * @author M.Kergall
+ */
+public class DouglasPeuckerReducer {
+
+    /**
+     * Reduce the number of points in a shape using the Douglas-Peucker
+     * algorithm
+     *
+     * @param shape     The shape to reduce
+     * @param tolerance The tolerance to decide whether or not to keep a point, in the
+     *                  coordinate system of the points (micro-degrees here)
+     * @return the reduced shape
+     */
+    public static List<GeoPoint> reduceWithTolerance(List<GeoPoint> shape,
+                                                     double tolerance) {
+        int n = shape.size();
+        // if a shape has 2 or less points it cannot be reduced
+        if (tolerance <= 0 || n < 3) {
+            return shape;
+        }
+
+        boolean[] marked = new boolean[n]; //vertex indexes to keep will be marked as "true"
+        for (int i = 1; i < n - 1; i++)
+            marked[i] = false;
+        // automatically add the first and last point to the returned shape
+        marked[0] = marked[n - 1] = true;
+
+        // the first and last points in the original shape are
+        // used as the entry point to the algorithm.
+        douglasPeuckerReduction(
+                shape, // original shape
+                marked, // reduced shape
+                tolerance, // tolerance
+                0, // index of first point
+                n - 1 // index of last point
+        );
+
+        // all done, return the reduced shape
+        ArrayList<GeoPoint> newShape = new ArrayList<GeoPoint>(n); // the new shape to return
+        for (int i = 0; i < n; i++) {
+            if (marked[i])
+                newShape.add(shape.get(i));
+        }
+        return newShape;
+    }
+
+    /**
+     * Reduce the points in shape between the specified first and last index.
+     * Mark the points to keep in marked[]
+     *
+     * @param shape     The original shape
+     * @param marked    The points to keep (marked as true)
+     * @param tolerance The tolerance to determine if a point is kept
+     * @param firstIdx  The index in original shape's point of the starting point for
+     *                  this line segment
+     * @param lastIdx   The index in original shape's point of the ending point for
+     *                  this line segment
+     */
+    private static void douglasPeuckerReduction(List<GeoPoint> shape, boolean[] marked,
+                                                double tolerance, int firstIdx, int lastIdx) {
+        if (lastIdx <= firstIdx + 1) {
+            // overlapping indexes, just return
+            return;
+        }
+
+        // loop over the points between the first and last points
+        // and find the point that is the farthest away
+
+        double maxDistance = 0.0;
+        int indexFarthest = 0;
+
+        GeoPoint firstPoint = shape.get(firstIdx);
+        GeoPoint lastPoint = shape.get(lastIdx);
+
+        for (int idx = firstIdx + 1; idx < lastIdx; idx++) {
+            GeoPoint point = shape.get(idx);
+
+            double distance = orthogonalDistance(point, firstPoint, lastPoint);
+
+            // keep the point with the greatest distance
+            if (distance > maxDistance) {
+                maxDistance = distance;
+                indexFarthest = idx;
+            }
+        }
+
+        if (maxDistance > tolerance) {
+            //The farthest point is outside the tolerance: it is marked and the algorithm continues.
+            marked[indexFarthest] = true;
+
+            // reduce the shape between the starting point to newly found point
+            douglasPeuckerReduction(shape, marked, tolerance, firstIdx, indexFarthest);
+
+            // reduce the shape between the newly found point and the finishing point
+            douglasPeuckerReduction(shape, marked, tolerance, indexFarthest, lastIdx);
+        }
+        //else: the farthest point is within the tolerance, the whole segment is discarded.
+    }
+
+    /**
+     * Calculate the orthogonal distance from the line joining the lineStart and
+     * lineEnd points to point
+     *
+     * @param point     The point the distance is being calculated for
+     * @param lineStart The point that starts the line
+     * @param lineEnd   The point that ends the line
+     * @return The distance in points coordinate system
+     */
+    public static double orthogonalDistance(GeoPoint point, GeoPoint lineStart, GeoPoint lineEnd) {
+        double area = Math.abs(
+                (
+                        1.0 * lineStart.latitudeE6 * lineEnd.longitudeE6
+                                + 1.0 * lineEnd.latitudeE6 * point.longitudeE6
+                                + 1.0 * point.latitudeE6 * lineStart.longitudeE6
+                                - 1.0 * lineEnd.latitudeE6 * lineStart.longitudeE6
+                                - 1.0 * point.latitudeE6 * lineEnd.longitudeE6
+                                - 1.0 * lineStart.latitudeE6 * point.longitudeE6
+                ) / 2.0
+        );
+
+        double bottom = Math.hypot(
+                lineStart.latitudeE6 - lineEnd.latitudeE6,
+                lineStart.longitudeE6 - lineEnd.longitudeE6
+        );
+
+        return (area / bottom * 2.0);
+    }
+}
diff --git a/vtm-app/src/org/osmdroid/utils/HttpConnection.java b/vtm-app/src/org/osmdroid/utils/HttpConnection.java
new file mode 100644
index 00000000..89a9d33e
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/utils/HttpConnection.java
@@ -0,0 +1,119 @@
+package org.osmdroid.utils;
+
+import android.util.Log;
+
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A "very very simple to use" class for performing http get and post requests.
+ * So many ways to do that, and potential subtle issues.
+ * If complexity should be added to handle even more issues, complexity should be put here and only here.
+ * <p/>
+ * Typical usage:
+ * <pre>HttpConnection connection = new HttpConnection();
+ * connection.doGet("http://www.google.com");
+ * InputStream stream = connection.getStream();
+ * if (stream != null) {
+ * 	//use this stream, for buffer reading, or XML SAX parsing, or whatever...
+ * }
+ * connection.close();</pre>
+ */
+public class HttpConnection {
+    private final static int TIMEOUT_CONNECTION = 3000; //ms
+    private final static int TIMEOUT_SOCKET = 10000; //ms
+
+    private static OkHttpClient client;
+    private InputStream stream;
+    private String mUserAgent;
+    private Response response;
+
+    private static OkHttpClient getOkHttpClient() {
+        if (client == null) {
+            client = new OkHttpClient();
+            client.setConnectTimeout(TIMEOUT_CONNECTION, TimeUnit.MILLISECONDS);
+            client.setReadTimeout(TIMEOUT_SOCKET, TimeUnit.MILLISECONDS);
+        }
+        return client;
+    }
+
+    public HttpConnection() {
+        /*
+        client = new OkHttpClient();
+        client.setConnectTimeout(TIMEOUT_CONNECTION, TimeUnit.MILLISECONDS);
+        client.setReadTimeout(TIMEOUT_SOCKET, TimeUnit.MILLISECONDS);
+        */
+    }
+
+    public void setUserAgent(String userAgent) {
+        mUserAgent = userAgent;
+    }
+
+    public void doGet(final String url) {
+        try {
+            Request.Builder request = new Request.Builder().url(url);
+            if (mUserAgent != null)
+                request.addHeader("User-Agent", mUserAgent);
+            response = getOkHttpClient().newCall(request.build()).execute();
+            Integer status = response.code();
+            if (status != 200) {
+                Log.e(BonusPackHelper.LOG_TAG, "Invalid response from server: " + status.toString());
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @return the opened InputStream, or null if creation failed for any reason.
+     */
+    public InputStream getStream() {
+        try {
+            if (response == null)
+                return null;
+            stream = response.body().byteStream();
+            return stream;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * @return the whole content as a String, or null if creation failed for any reason.
+     */
+    public String getContentAsString() {
+        try {
+            if (response == null)
+                return null;
+            return response.body().string();
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * Calling close once is mandatory.
+     */
+    public void close() {
+        if (stream != null) {
+            try {
+                stream.close();
+                stream = null;
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        /*
+        if (client != null)
+            client = null;
+        */
+    }
+
+}
diff --git a/vtm-app/src/org/osmdroid/utils/MathConstants.java b/vtm-app/src/org/osmdroid/utils/MathConstants.java
new file mode 100644
index 00000000..bfb2792a
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/utils/MathConstants.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.osmdroid.utils;
+
+public class MathConstants {
+
+    public static final double PI180E6 = (Math.PI / 180) / 1000000.0;
+    public static final double PIx4 = Math.PI * 4;
+
+}
diff --git a/vtm-app/src/org/osmdroid/utils/PolylineEncoder.java b/vtm-app/src/org/osmdroid/utils/PolylineEncoder.java
new file mode 100644
index 00000000..ffef0484
--- /dev/null
+++ b/vtm-app/src/org/osmdroid/utils/PolylineEncoder.java
@@ -0,0 +1,94 @@
+package org.osmdroid.utils;
+
+import org.oscim.core.GeoPoint;
+
+import java.util.ArrayList;
+
+/**
+ * Methods to encode and decode a polyline with Google polyline
+ * encoding/decoding scheme. See
+ * https://developers.google.com/maps/documentation/utilities/polylinealgorithm
+ */
+public class PolylineEncoder {
+
+    private static StringBuffer encodeSignedNumber(int num) {
+        int sgn_num = num << 1;
+        if (num < 0) {
+            sgn_num = ~(sgn_num);
+        }
+        return (encodeNumber(sgn_num));
+    }
+
+    private static StringBuffer encodeNumber(int num) {
+        StringBuffer encodeString = new StringBuffer();
+        while (num >= 0x20) {
+            int nextValue = (0x20 | (num & 0x1f)) + 63;
+            encodeString.append((char) (nextValue));
+            num >>= 5;
+        }
+        num += 63;
+        encodeString.append((char) (num));
+        return encodeString;
+    }
+
+    /**
+     * Encode a polyline with Google polyline encoding method
+     *
+     * @param polyline  the polyline
+     * @param precision 1 for a 6 digits encoding, 10 for a 5 digits encoding.
+     * @return the encoded polyline, as a String
+     */
+    public static String encode(ArrayList<GeoPoint> polyline, int precision) {
+        StringBuffer encodedPoints = new StringBuffer();
+        int prev_lat = 0, prev_lng = 0;
+        for (GeoPoint trackpoint : polyline) {
+            int lat = trackpoint.latitudeE6 / precision;
+            int lng = trackpoint.longitudeE6 / precision;
+            encodedPoints.append(encodeSignedNumber(lat - prev_lat));
+            encodedPoints.append(encodeSignedNumber(lng - prev_lng));
+            prev_lat = lat;
+            prev_lng = lng;
+        }
+        return encodedPoints.toString();
+    }
+
+    /**
+     * Decode a "Google-encoded" polyline
+     *
+     * @param encodedString ...
+     * @param precision     1 for a 6 digits encoding, 10 for a 5 digits encoding.
+     * @return the polyline.
+     */
+    public static ArrayList<GeoPoint> decode(String encodedString, int precision) {
+        ArrayList<GeoPoint> polyline = new ArrayList<GeoPoint>();
+        int index = 0;
+        int len = encodedString.length();
+        int lat = 0, lng = 0;
+
+        while (index < len) {
+            int b, shift = 0, result = 0;
+            do {
+                b = encodedString.charAt(index++) - 63;
+                result |= (b & 0x1f) << shift;
+                shift += 5;
+            } while (b >= 0x20);
+            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
+            lat += dlat;
+
+            shift = 0;
+            result = 0;
+            do {
+                b = encodedString.charAt(index++) - 63;
+                result |= (b & 0x1f) << shift;
+                shift += 5;
+            } while (b >= 0x20);
+            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
+            lng += dlng;
+
+            GeoPoint p = new GeoPoint(lat * precision, lng * precision);
+            polyline.add(p);
+        }
+
+        return polyline;
+    }
+}