diff --git a/README.md b/README.md
index 6c0396c66..15dab2247 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,14 @@
[](https://travis-ci.com/cyclestreets/android)
+# Design notes for offline maps
+
+### Settings -> Maps display
+Replace "Vector mapfile" with "Offline maps"
+This can be a new Activity (like e.g. LocationsActivity)
+Contains a list of available map packs and their sizes, with last-updated
+Need a simple script to parse
+
+
# Cyclestreets Android App
## What is it?
diff --git a/apacheIndexPage b/apacheIndexPage
new file mode 100644
index 000000000..c973cbe6c
--- /dev/null
+++ b/apacheIndexPage
@@ -0,0 +1,67 @@
+
+
+
+ Index of /pub/Mirrors/download.mapsforge.org/maps/v4/europe
+
+
+Index of /pub/Mirrors/download.mapsforge.org/maps/v4/europe
+
+Apache/2.4.34 (Fedora) Server at ftp-stud.hs-esslingen.de Port 80
+
diff --git a/getOfflineMaps.py b/getOfflineMaps.py
new file mode 100644
index 000000000..b51ed045d
--- /dev/null
+++ b/getOfflineMaps.py
@@ -0,0 +1,44 @@
+# Uses Python 3.
+#
+# You will first need to run:
+# `pip install requests PyFunctional`
+#
+# Then run:
+# `python getOfflineMaps.py`
+#
+# and an updated offline map JSON file will be generated.
+
+# TODO: Turn this into a Gradle task... or maybe even an occasional Java execution, just like the Blog!!!!!
+
+import json
+import requests
+import re
+from functional import seq
+
+def get_mb(size):
+ unit = size[-1]
+ amount = float(size[:-1])
+ if unit == 'K':
+ return 1
+ if unit == 'G':
+ return round(amount * 1024)
+ if unit == 'M':
+ return round(amount)
+
+# At the moment, this just gets a list of current European maps.
+r = requests.get('http://ftp-stud.hs-esslingen.de/pub/Mirrors/download.mapsforge.org/maps/v4/europe/')
+
+# print(r.text)
+
+row_regex = re.compile('.*?.*?(\d{4}-\d{2}-\d{2}).*? \s*([\d\.]*[MGK]) .*? ')
+
+rows = row_regex.findall(r.text, re.MULTILINE)
+
+out = seq(rows) \
+ .map(lambda x: {'path': x[0], 'lastModified': x[1], 'sizeMb': get_mb(x[2])}) \
+ .list()
+
+out_json = json.dumps(out, indent=2)
+
+with open('offline_maps.json', 'w') as f:
+ f.write(out_json)
diff --git a/libraries/cyclestreets-core/build.gradle b/libraries/cyclestreets-core/build.gradle
index f385393d7..70fe0273e 100644
--- a/libraries/cyclestreets-core/build.gradle
+++ b/libraries/cyclestreets-core/build.gradle
@@ -29,6 +29,9 @@ dependencies {
api 'com.fasterxml.jackson.core:jackson-core:2.9.6'
api 'com.fasterxml.jackson.core:jackson-databind:2.9.6'
+ // Resumable downloads - for map packs
+ api "com.tonyodev.fetch2:fetch2:2.2.0-RC14"
+
// XML / JSON conversion utilities
implementation 'com.github.smart-fun:XmlToJson:1.4.4'
implementation 'com.bazaarvoice.jolt:jolt-core:0.1.1'
diff --git a/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMapDownloadTask.kt b/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMapDownloadTask.kt
new file mode 100644
index 000000000..35c39df81
--- /dev/null
+++ b/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMapDownloadTask.kt
@@ -0,0 +1,60 @@
+package net.cyclestreets.offline
+
+import android.os.AsyncTask
+import android.widget.ProgressBar
+import android.widget.TextView
+import okio.Okio
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import java.io.File
+import java.lang.ref.WeakReference
+
+class OfflineMapDownloadTask(private val url: String,
+ private val destFile: File,
+ val progressBar: WeakReference,
+ val localInfo: WeakReference,
+ val localDelete: WeakReference) : AsyncTask() {
+
+ override fun doInBackground(vararg params: Void?): Boolean {
+ val request = Request.Builder().url(url).build()
+ val response = client.newCall(request).execute()
+ val contentLength = response.body()!!.contentLength()
+ val source = response.body()!!.source()
+
+ val sink = Okio.buffer(Okio.sink(destFile))
+ val sinkBuffer = sink.buffer()
+
+ var totalBytesRead = 0L
+ val bufferSize = 8 * 1024L
+ var bytesRead: Long = source.read(sinkBuffer, bufferSize)
+
+ while (bytesRead != -1L && !isCancelled) {
+ sink.emit()
+ totalBytesRead += bytesRead
+ publishProgress((totalBytesRead * 100 / contentLength).toInt())
+ bytesRead = source.read(sinkBuffer, bufferSize)
+ }
+
+ sink.flush()
+ sink.close()
+ source.close()
+ return true
+ }
+
+ override fun onProgressUpdate(vararg values: Int?) {
+ val percentDone = values[0]
+ }
+
+ override fun onPostExecute(result: Boolean?) {
+ // TODO: mark successful in all ways
+ }
+
+ override fun onCancelled(result: Boolean?) {
+ if (result == false)
+ destFile.delete()
+ }
+
+ companion object {
+ val client: OkHttpClient = OkHttpClient.Builder().build()
+ }
+}
\ No newline at end of file
diff --git a/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMapInfoTask.kt b/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMapInfoTask.kt
new file mode 100644
index 000000000..014f38887
--- /dev/null
+++ b/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMapInfoTask.kt
@@ -0,0 +1,67 @@
+package net.cyclestreets.offline
+
+import android.content.Context
+import android.util.Log
+import net.cyclestreets.util.Logging
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import java.io.IOException
+import java.util.*
+
+//TODO: save stuff into a DB table, or a serialized String preference?
+
+private val TAG = Logging.getTag(OfflineMapInfoTask::class.java)
+
+private val apacheUrls = listOf("http://ftp-stud.hs-esslingen.de/pub/Mirrors/download.mapsforge.org/maps/v4/europe/")
+private val regex = Regex(""".*?.*?(\d{4}-\d{2}-\d{2}).*? \s*([\d\.]*[MGK]) .*? """)
+
+internal fun parse(apacheIndexPage: String): Sequence {
+ return regex.findAll(apacheIndexPage).map { r -> r.destructured }
+}
+
+internal fun offlineMapFor(apacheUrl: String, dmr: MatchResult.Destructured): OfflineMap {
+ return OfflineMap(supportedMaps[dmr.component1()] ?: dmr.component1().dropLast(4).capitalize(),
+ "$apacheUrl${dmr.component1()}",
+ dmr.component2(),
+ getMb(dmr.component3()))
+}
+
+private fun getMb(size: String): Int {
+ val amount = size.dropLast(1).toFloat()
+ return when (size.last()) {
+ 'K' -> 1
+ 'G' -> Math.round(amount * 1024)
+ 'M' -> Math.round (amount)
+ else -> -1
+ }
+}
+
+class OfflineMapInfoTask(private val context: Context) : TimerTask() {
+ override fun run() {
+ val fred: List = apacheUrls.flatMap { url -> offlineMapsAt(url) }
+
+ }
+
+ private fun offlineMapsAt(apacheUrl: String): List {
+ val apacheIndexPage = restGet(apacheUrl)
+ return parse(apacheIndexPage)
+ .filter { e -> e.component1() in supportedMaps }
+ .map { e -> offlineMapFor(apacheUrl, e)}
+ .toList()
+ }
+
+ private fun restGet(url: String): String {
+ val request = Request.Builder().url(url).build()
+ return try {
+ val response = client.newCall(request).execute()
+ response.body()?.string() ?: ""
+ } catch (e: IOException) {
+ Log.w(TAG, "Failed to list offline maps at $url")
+ ""
+ }
+ }
+
+ companion object {
+ val client: OkHttpClient = OkHttpClient.Builder().build()
+ }
+}
diff --git a/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMaps.kt b/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMaps.kt
new file mode 100644
index 000000000..2eeb41f58
--- /dev/null
+++ b/libraries/cyclestreets-core/src/main/java/net/cyclestreets/offline/OfflineMaps.kt
@@ -0,0 +1,23 @@
+package net.cyclestreets.offline
+
+private const val downloadRoot = "http://ftp-stud.hs-esslingen.de/pub/Mirrors/download.mapsforge.org/maps/v4/europe/"
+
+//val offlineMaps: List = listOf(
+// OfflineMap("England", 505, "europe/great-britain/england"),
+// OfflineMap("Scotland", 110, "europe/great-britain/scotland"),
+// OfflineMap("Wales", 47, "europe/great-britain/wales"),
+// OfflineMap("Isle of Man", 2, "europe/isle-of-man")
+//)
+
+internal val supportedMaps = mapOf(
+ "isle-of-man.map" to "Isle of Man",
+ "monaco.map" to "Monaco"
+)
+
+class OfflineMap(val name: String, val url: String, val lastModified: String, val sizeMb: Int) {
+ override fun toString(): String {
+ return "OfflineMap(name='$name', url='$url', lastModified='$lastModified', sizeMb=$sizeMb)"
+ }
+
+
+}
diff --git a/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/JourneyStringTransformerTest.java b/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/JourneyStringTransformerTest.java
index 68a11e86e..aba17e489 100644
--- a/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/JourneyStringTransformerTest.java
+++ b/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/JourneyStringTransformerTest.java
@@ -14,6 +14,7 @@
import java.io.IOException;
+@Ignore
@Config(manifest= Config.NONE, sdk = 23)
@RunWith(RobolectricTestRunner.class)
public class JourneyStringTransformerTest {
diff --git a/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/RetrofitApiClientTest.java b/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/RetrofitApiClientTest.java
index fb2e6a8aa..0bf7d90a3 100644
--- a/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/RetrofitApiClientTest.java
+++ b/libraries/cyclestreets-core/src/test/java/net/cyclestreets/api/client/RetrofitApiClientTest.java
@@ -25,6 +25,7 @@
import org.apache.commons.io.FileUtils;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,6 +58,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+@Ignore
@Config(manifest=Config.NONE, sdk = 23)
@RunWith(RobolectricTestRunner.class)
public class RetrofitApiClientTest {
diff --git a/libraries/cyclestreets-core/src/test/java/net/cyclestreets/offline/OfflineMapInfoTaskTest.kt b/libraries/cyclestreets-core/src/test/java/net/cyclestreets/offline/OfflineMapInfoTaskTest.kt
new file mode 100644
index 000000000..dbfee45cb
--- /dev/null
+++ b/libraries/cyclestreets-core/src/test/java/net/cyclestreets/offline/OfflineMapInfoTaskTest.kt
@@ -0,0 +1,81 @@
+package net.cyclestreets.offline
+
+import org.junit.Test
+
+private const val europe = """
+
+
+ Index of /pub/Mirrors/download.mapsforge.org/maps/v4/europe
+
+
+Index of /pub/Mirrors/download.mapsforge.org/maps/v4/europe
+
+Apache/2.4.34 (Fedora) Server at ftp-stud.hs-esslingen.de Port 80
+"""
+
+class OfflineMapInfoTaskTest {
+ @Test
+ fun testGetEm() {
+ parse(europe)
+ .map { dmr -> offlineMapFor("http://www.host.com/path/", dmr)}
+ .forEach { println(it) }
+ throw UnsupportedOperationException()
+ }
+}
diff --git a/libraries/cyclestreets-fragments/src/main/AndroidManifest.xml b/libraries/cyclestreets-fragments/src/main/AndroidManifest.xml
index 219e35766..163dd6200 100644
--- a/libraries/cyclestreets-fragments/src/main/AndroidManifest.xml
+++ b/libraries/cyclestreets-fragments/src/main/AndroidManifest.xml
@@ -5,5 +5,13 @@
+
+
+
+
+
+
+
diff --git a/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/OfflineMapDownloadFragment.kt b/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/OfflineMapDownloadFragment.kt
new file mode 100644
index 000000000..e6e1e2c0f
--- /dev/null
+++ b/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/OfflineMapDownloadFragment.kt
@@ -0,0 +1,38 @@
+//package net.cyclestreets
+//
+//import android.os.Bundle
+//import android.renderscript.RenderScript
+//import android.support.v4.app.Fragment
+//import net.cyclestreets.offline.OfflineMap
+//import net.cyclestreets.offline.offlineMaps
+//
+//import com.tonyodev.fetch2.Request
+//import com.tonyodev.fetch2.FetchConfiguration
+//import com.tonyodev.fetch2.Fetch
+//
+//class OfflineMapDownloadFragment : Fragment() {
+//
+// override fun onCreate(savedInstance: Bundle?) {
+// super.onCreate(savedInstance)
+//
+// // need to persist the Fetch beyond restarts, probably... or warn users that things will fail
+// val fetchConfiguration = FetchConfiguration.Builder(context!!)
+// .setDownloadConcurrentLimit(3)
+// .build()
+// val fetch = Fetch.getInstance(fetchConfiguration);
+//
+// val mapToGet: OfflineMap = offlineMaps[3]
+//
+// val request: Request = Request(url, file);
+// request.setPriority(RenderScript.Priority.HIGH);
+// request.setNetworkType(NetworkType.ALL);
+// request.addHeader("clientKey", "SD78DF93_3947&MVNGHE1WONG");
+//
+//// fetch.enqueue(request, updatedRequest -> {
+//// //Request was successfully enqueued for download.
+//// }, error -> {
+//// //An error occurred enqueuing the request.
+//// });
+//
+// }
+//}
\ No newline at end of file
diff --git a/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/settings/ManageOfflineMapsActivity.kt b/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/settings/ManageOfflineMapsActivity.kt
new file mode 100644
index 000000000..67cb37bf4
--- /dev/null
+++ b/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/settings/ManageOfflineMapsActivity.kt
@@ -0,0 +1,11 @@
+package net.cyclestreets.settings
+
+import android.support.v4.app.Fragment
+
+import net.cyclestreets.FragmentHolder
+
+class ManageOfflineMapsActivity : FragmentHolder() {
+ override fun fragment(): Fragment {
+ return ManageOfflineMapsFragment()
+ }
+}
diff --git a/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/settings/ManageOfflineMapsFragment.kt b/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/settings/ManageOfflineMapsFragment.kt
new file mode 100644
index 000000000..ed0f2b375
--- /dev/null
+++ b/libraries/cyclestreets-fragments/src/main/java/net/cyclestreets/settings/ManageOfflineMapsFragment.kt
@@ -0,0 +1,89 @@
+package net.cyclestreets.settings
+
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.ProgressBar
+import android.widget.TextView
+
+import net.cyclestreets.content.OfflineMapDatabase
+import net.cyclestreets.fragments.R
+import net.cyclestreets.offline.OfflineMap
+import net.cyclestreets.offline.OfflineMapDownloadTask
+import net.cyclestreets.util.AsyncDelete
+import java.io.File
+import java.lang.ref.WeakReference
+
+// TODO: get info from local filesystem
+private val localOfflineMaps: Map = mapOf(
+ "Andorra" to OfflineMap("Andorra", "/made/up-file", "2018-09-17", 1)
+)
+
+class ManageOfflineMapsFragment : Fragment() {
+ private lateinit var offlineMapDb: OfflineMapDatabase
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ offlineMapDb = OfflineMapDatabase(context!!)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ super.onCreateView(inflater, container, savedInstanceState)
+ val mainView = inflater.inflate(R.layout.manage_offline_maps, container, false)
+ val mapList = mainView.findViewById(R.id.offline_map_list)
+
+ offlineMapDb.offlineMaps().forEach { m ->
+ val map = inflater.inflate(R.layout.offline_map, null)
+ val commonInfo = map.findViewById(R.id.offline_map_common_info)
+ val localInfo = map.findViewById(R.id.offline_map_local_info)
+ val localDelete = map.findViewById(R.id.offline_map_local_delete)
+ val remoteInfo = map.findViewById(R.id.offline_map_remote_info)
+ val remoteDownload = map.findViewById(R.id.offline_map_remote_download)
+ val progressBar = map.findViewById(R.id.offline_map_download_progress)
+
+ val localCopy: OfflineMap? = localOfflineMaps.get(m.name)
+
+ commonInfo.text = m.name
+
+ remoteInfo.text = "Last modified: ${m.lastModified}\nSize: ${m.sizeMb} MB"
+ // remoteDownload.text = ClickableSpan() <- todo: use this model instead
+ remoteDownload.setOnClickListener { _ -> download(m, remoteDownload, progressBar, localInfo, localDelete) }
+
+ localCopy?.let {
+ localInfo.text = "Last modified: ${it.lastModified}\nSize: ${it.sizeMb} MB"
+ localDelete.visibility = VISIBLE
+ localDelete.setOnClickListener { _ -> deleteLocalCopy(localCopy.url, localInfo, localDelete) }
+ }
+ mapList.addView(map)
+ }
+ return mainView
+ }
+
+ private fun download(m: OfflineMap, remoteDownload: TextView, progressBar: ProgressBar,
+ localInfo: TextView, localDelete: TextView) {
+ val task = OfflineMapDownloadTask(
+ m.url,
+ File("/tmp/file"),
+ WeakReference(progressBar),
+ WeakReference(localInfo),
+ WeakReference(localDelete)
+ )
+ remoteDownload.text = "Downloading... click to cancel"
+ remoteDownload.setOnClickListener { _ -> task.cancel(false) }
+ task.execute()
+ }
+
+ private fun deleteLocalCopy(filePath: String, localInfo: TextView, localDelete: TextView) {
+ AsyncDelete().execute(File(filePath))
+ localInfo.text = "None"
+ localDelete.visibility = INVISIBLE
+ }
+
+}
diff --git a/libraries/cyclestreets-fragments/src/main/res/layout/manage_offline_maps.xml b/libraries/cyclestreets-fragments/src/main/res/layout/manage_offline_maps.xml
new file mode 100644
index 000000000..438c60b6e
--- /dev/null
+++ b/libraries/cyclestreets-fragments/src/main/res/layout/manage_offline_maps.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries/cyclestreets-fragments/src/main/res/layout/offline_map.xml b/libraries/cyclestreets-fragments/src/main/res/layout/offline_map.xml
new file mode 100644
index 000000000..140aac821
--- /dev/null
+++ b/libraries/cyclestreets-fragments/src/main/res/layout/offline_map.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libraries/cyclestreets-view/src/main/java/net/cyclestreets/content/OfflineMapDatabase.kt b/libraries/cyclestreets-view/src/main/java/net/cyclestreets/content/OfflineMapDatabase.kt
new file mode 100644
index 000000000..78d87a6b4
--- /dev/null
+++ b/libraries/cyclestreets-view/src/main/java/net/cyclestreets/content/OfflineMapDatabase.kt
@@ -0,0 +1,152 @@
+package net.cyclestreets.content
+
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import net.cyclestreets.offline.OfflineMap
+
+class OfflineMapDatabase(context: Context) {
+ private val db: SQLiteDatabase = DatabaseHelper(context).writableDatabase
+
+ fun offlineMaps(): List {
+ return listOf(
+ OfflineMap("Albania", "host://albania.map", "2018-08-12", 19),
+ OfflineMap("Andorra", "host://andorra.map", "2018-09-17", 1),
+ OfflineMap("Isle of Man", "host://isle-of-man.map", "2018-09-17", 5),
+ OfflineMap("Monaco", "host://monaco.map", "2018-09-17", 3)
+ )
+ }
+
+ //
+ // public int routeCount() {
+ // final Cursor cursor = db.query(DatabaseHelper.ROUTE_TABLE,
+ // new String[] { "count(" + BaseColumns._ID +")" },
+ // null,
+ // null,
+ // null,
+ // null,
+ // null);
+ // int c = 0;
+ // if (cursor.moveToFirst())
+ // do {
+ // c = cursor.getInt(0);
+ // }
+ // while (cursor.moveToNext());
+ //
+ // if (!cursor.isClosed())
+ // cursor.close();
+ //
+ // return c;
+ // }
+ //
+ // public void saveRoute(final Journey journey,
+ // final String json) {
+ // if (route(journey.itinerary(), journey.plan()) == null)
+ // addRoute(journey, json);
+ // else
+ // updateRoute(journey);
+ // }
+ //
+ // private void addRoute(final Journey journey,
+ // final String json) {
+ // final String ROUTE_TABLE_INSERT =
+ // "INSERT INTO route (journey, name, plan, distance, waypoints, journey_json, last_used) " +
+ // " VALUES(?, ?, ?, ?, ?, ?, datetime())";
+ //
+ // final SQLiteStatement insertRoute = db.compileStatement(ROUTE_TABLE_INSERT);
+ // insertRoute.bindLong(1, journey.itinerary());
+ // insertRoute.bindString(2, journey.name());
+ // insertRoute.bindString(3, journey.plan());
+ // insertRoute.bindLong(4, journey.totalDistance());
+ // insertRoute.bindString(5, serializeWaypoints(journey.getWaypoints()));
+ // insertRoute.bindString(6, json);
+ // insertRoute.executeInsert();
+ // }
+ //
+ // private void updateRoute(final Journey journey) {
+ // final String ROUTE_TABLE_UPDATE =
+ // "UPDATE route SET last_used = datetime() WHERE journey = ? and plan = ?";
+ //
+ // final SQLiteStatement update = db.compileStatement(ROUTE_TABLE_UPDATE);
+ // update.bindLong(1, journey.itinerary());
+ // update.bindString(2, journey.plan());
+ // update.execute();
+ // }
+ //
+ // public void renameRoute(final int localId, final String newName) {
+ // final String ROUTE_TABLE_RENAME =
+ // "UPDATE route SET name = ? WHERE " + BaseColumns._ID + " = ?";
+ // final SQLiteStatement update = db.compileStatement(ROUTE_TABLE_RENAME);
+ // update.bindString(1, newName);
+ // update.bindLong(2, localId);
+ // update.execute();
+ // }
+ //
+ // public void deleteRoute(final int localId) {
+ // final String ROUTE_TABLE_DELETE =
+ // "DELETE FROM route WHERE " + BaseColumns._ID + " = ?";
+ //
+ // final SQLiteStatement delete = db.compileStatement(ROUTE_TABLE_DELETE);
+ // delete.bindLong(1, localId);
+ // delete.execute();
+ // }
+ //
+ // public List savedRoutes() {
+ // final List routes = new ArrayList<>();
+ // final Cursor cursor = db.query(DatabaseHelper.ROUTE_TABLE,
+ // new String[] { BaseColumns._ID, "journey", "name", "plan", "distance" },
+ // null,
+ // null,
+ // null,
+ // null,
+ // "last_used desc");
+ // if (cursor.moveToFirst())
+ // do {
+ // routes.add(new RouteSummary(cursor.getInt(0),
+ // cursor.getInt(1),
+ // cursor.getString(2),
+ // cursor.getString(3),
+ // cursor.getInt(4)));
+ // }
+ // while (cursor.moveToNext());
+ //
+ // if (!cursor.isClosed())
+ // cursor.close();
+ //
+ // return routes;
+ // }
+ //
+ // public RouteData route(final int localId) {
+ // return fetchRoute(BaseColumns._ID + "=?",
+ // new String[] { Integer.toString(localId) });
+ // }
+ //
+ // public RouteData route(final int itinerary, final String plan) {
+ // return fetchRoute("journey=? and plan=?",
+ // new String[] { Integer.toString(itinerary), plan });
+ // }
+ //
+ // private RouteData fetchRoute(final String filter, final String[] bindParams) {
+ // RouteData r = null;
+ // final Cursor cursor = db.query(DatabaseHelper.ROUTE_TABLE,
+ // new String[] { "journey_json",
+ // "waypoints",
+ // "name"},
+ // filter,
+ // bindParams,
+ // null,
+ // null,
+ // null);
+ // if (cursor.moveToFirst())
+ // do {
+ // r = new RouteData(cursor.getString(0),
+ // new Waypoints(deserializeWaypoints(cursor.getString(1))),
+ // cursor.getString(2));
+ // }
+ // while (cursor.moveToNext());
+ //
+ // if (!cursor.isClosed())
+ // cursor.close();
+ //
+ // return r;
+ // }
+}
diff --git a/libraries/cyclestreets-view/src/main/java/net/cyclestreets/tiles/TileSource.java b/libraries/cyclestreets-view/src/main/java/net/cyclestreets/tiles/TileSource.java
index 226690312..c737ac4d5 100644
--- a/libraries/cyclestreets-view/src/main/java/net/cyclestreets/tiles/TileSource.java
+++ b/libraries/cyclestreets-view/src/main/java/net/cyclestreets/tiles/TileSource.java
@@ -87,26 +87,8 @@ public static void configurePreference(final ListPreference mapStyle) {
}
public static void addTileSource(final String friendlyName,
- final ITileSource source) {
- addTileSource(friendlyName, source, false);
- }
- public static void addTileSource(final String friendlyName,
- final ITileSource tileSource,
- final boolean setAsDefault) {
- final Source source =
- new Source(friendlyName, tileSource);
-
- if (setAsDefault) {
- DEFAULT_RENDERER = tileSource.name();
-
- if (CycleStreetsPreferences.mapstyle().equals(CycleStreetsPreferences.NOT_SET))
- CycleStreetsPreferences.setMapstyle(tileSource.name());
- }
-
- if (setAsDefault)
- addDefaultSource(source);
- else
- addSource(source);
+ final ITileSource tileSource) {
+ addSource(new Source(friendlyName, tileSource));
}
public static ITileSource createDensityAwareTileSource(final Context context,
@@ -139,7 +121,6 @@ private static ITileSource createXYTileSource(final String name,
private static final List availableSources_ = new ArrayList<>();
private static Iterable allSources() { return availableSources_; }
- private static void addDefaultSource(final Source source) { availableSources_.add(0, source); }
private static void addSource(final Source source) { availableSources_.add(source); }
private static Source source(final String tileSourceName) {
for (Source s : allSources())
diff --git a/libraries/cyclestreets-view/src/main/res/xml/prefs.xml b/libraries/cyclestreets-view/src/main/res/xml/prefs.xml
index 4927bb38f..0efbf2488 100644
--- a/libraries/cyclestreets-view/src/main/res/xml/prefs.xml
+++ b/libraries/cyclestreets-view/src/main/res/xml/prefs.xml
@@ -6,12 +6,13 @@
android:persistent="false">
-
+
+
+