mirror of
https://gitlab.com/oeffi/oeffi.git
synced 2025-07-07 21:58:48 +00:00
NetworkContentProvider: Remove downloading and usage of predefined station databases.
This commit is contained in:
parent
f17bf1f776
commit
6250043844
7 changed files with 42 additions and 553 deletions
|
@ -228,11 +228,6 @@
|
||||||
android:label="@string/stations_favorite_stations_title"
|
android:label="@string/stations_favorite_stations_title"
|
||||||
android:taskAffinity="de.schildbach.oeffi.stations" />
|
android:taskAffinity="de.schildbach.oeffi.stations" />
|
||||||
|
|
||||||
<provider
|
|
||||||
android:name=".stations.NetworkContentProvider"
|
|
||||||
android:authorities="de.schildbach.oeffi.networks"
|
|
||||||
android:exported="false" />
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name=".stations.FavoriteStationsProvider"
|
android:name=".stations.FavoriteStationsProvider"
|
||||||
android:authorities="de.schildbach.oeffi.stations.favorites"
|
android:authorities="de.schildbach.oeffi.stations.favorites"
|
||||||
|
|
|
@ -26,7 +26,6 @@ import okhttp3.HttpUrl;
|
||||||
|
|
||||||
public class Constants {
|
public class Constants {
|
||||||
public static final HttpUrl OEFFI_BASE_URL = HttpUrl.parse("https://oeffi.schildbach.de/");
|
public static final HttpUrl OEFFI_BASE_URL = HttpUrl.parse("https://oeffi.schildbach.de/");
|
||||||
public static final HttpUrl STATIONS_BASE_URL = OEFFI_BASE_URL.newBuilder().addPathSegment("stations").build();
|
|
||||||
public static final HttpUrl PLANS_BASE_URL = OEFFI_BASE_URL.newBuilder().addPathSegment("plans").build();
|
public static final HttpUrl PLANS_BASE_URL = OEFFI_BASE_URL.newBuilder().addPathSegment("plans").build();
|
||||||
public static final HttpUrl MESSAGES_BASE_URL = OEFFI_BASE_URL.newBuilder().addPathSegment("messages").build();
|
public static final HttpUrl MESSAGES_BASE_URL = OEFFI_BASE_URL.newBuilder().addPathSegment("messages").build();
|
||||||
public static final String PLANS_DIR = "plans";
|
public static final String PLANS_DIR = "plans";
|
||||||
|
|
|
@ -42,7 +42,6 @@ import de.schildbach.oeffi.R;
|
||||||
import de.schildbach.oeffi.TripAware;
|
import de.schildbach.oeffi.TripAware;
|
||||||
import de.schildbach.oeffi.directions.TimeSpec.DepArr;
|
import de.schildbach.oeffi.directions.TimeSpec.DepArr;
|
||||||
import de.schildbach.oeffi.stations.LineView;
|
import de.schildbach.oeffi.stations.LineView;
|
||||||
import de.schildbach.oeffi.stations.NetworkContentProvider;
|
|
||||||
import de.schildbach.oeffi.stations.StationContextMenu;
|
import de.schildbach.oeffi.stations.StationContextMenu;
|
||||||
import de.schildbach.oeffi.stations.StationDetailsActivity;
|
import de.schildbach.oeffi.stations.StationDetailsActivity;
|
||||||
import de.schildbach.oeffi.util.Formats;
|
import de.schildbach.oeffi.util.Formats;
|
||||||
|
@ -54,7 +53,6 @@ import de.schildbach.pte.NetworkId;
|
||||||
import de.schildbach.pte.dto.Fare;
|
import de.schildbach.pte.dto.Fare;
|
||||||
import de.schildbach.pte.dto.Line;
|
import de.schildbach.pte.dto.Line;
|
||||||
import de.schildbach.pte.dto.Location;
|
import de.schildbach.pte.dto.Location;
|
||||||
import de.schildbach.pte.dto.LocationType;
|
|
||||||
import de.schildbach.pte.dto.Point;
|
import de.schildbach.pte.dto.Point;
|
||||||
import de.schildbach.pte.dto.Position;
|
import de.schildbach.pte.dto.Position;
|
||||||
import de.schildbach.pte.dto.Stop;
|
import de.schildbach.pte.dto.Stop;
|
||||||
|
@ -72,7 +70,6 @@ import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
|
@ -695,13 +692,6 @@ public class TripDetailsActivity extends OeffiActivity implements LocationListen
|
||||||
if (leg.arrival.hasCoord()) {
|
if (leg.arrival.hasCoord()) {
|
||||||
mapView.setVisibility(View.VISIBLE);
|
mapView.setVisibility(View.VISIBLE);
|
||||||
mapView.setOnClickListener(new MapClickListener(leg.arrival));
|
mapView.setOnClickListener(new MapClickListener(leg.arrival));
|
||||||
} else if (leg.arrival.hasId()) {
|
|
||||||
final Point point = pointFromStationDb(leg.arrival.id);
|
|
||||||
if (point != null) {
|
|
||||||
mapView.setVisibility(View.VISIBLE);
|
|
||||||
mapView.setOnClickListener(new MapClickListener(new Location(LocationType.STATION, leg.arrival.id,
|
|
||||||
point, leg.arrival.place, leg.arrival.name)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,53 +930,6 @@ public class TripDetailsActivity extends OeffiActivity implements LocationListen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Point pointFromStationDb(final String id) {
|
|
||||||
final Cursor cursor = getContentResolver().query(
|
|
||||||
NetworkContentProvider.CONTENT_URI.buildUpon().appendPath(network.name()).build(),
|
|
||||||
new String[] { NetworkContentProvider.KEY_LAT, NetworkContentProvider.KEY_LON },
|
|
||||||
NetworkContentProvider.KEY_ID + "=?", new String[] { id }, null);
|
|
||||||
if (cursor == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
final Point point;
|
|
||||||
|
|
||||||
if (cursor.moveToFirst()) {
|
|
||||||
final int latColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LAT);
|
|
||||||
final int lonColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LON);
|
|
||||||
point = Point.from1E6(cursor.getInt(latColumnIndex), cursor.getInt(lonColumnIndex));
|
|
||||||
} else {
|
|
||||||
point = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.close();
|
|
||||||
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point pointFromStationDb(final String place, final String name) {
|
|
||||||
final Cursor cursor = getContentResolver().query(
|
|
||||||
NetworkContentProvider.CONTENT_URI.buildUpon().appendPath(network.name())
|
|
||||||
.appendQueryParameter(NetworkContentProvider.KEY_PLACE, place != null ? place : "")
|
|
||||||
.appendQueryParameter(NetworkContentProvider.KEY_NAME, name != null ? name : "").build(),
|
|
||||||
new String[] { NetworkContentProvider.KEY_LAT, NetworkContentProvider.KEY_LON }, null, null, null);
|
|
||||||
if (cursor == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
final Point point;
|
|
||||||
|
|
||||||
if (cursor.moveToFirst()) {
|
|
||||||
final int latColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LAT);
|
|
||||||
final int lonColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LON);
|
|
||||||
point = Point.from1E6(cursor.getInt(latColumnIndex), cursor.getInt(lonColumnIndex));
|
|
||||||
} else {
|
|
||||||
point = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.close();
|
|
||||||
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareTripShort() {
|
private void shareTripShort() {
|
||||||
final Intent intent = new Intent(Intent.ACTION_SEND);
|
final Intent intent = new Intent(Intent.ACTION_SEND);
|
||||||
intent.setType("text/plain");
|
intent.setType("text/plain");
|
||||||
|
@ -1113,19 +1056,6 @@ public class TripDetailsActivity extends OeffiActivity implements LocationListen
|
||||||
if (location.hasCoord())
|
if (location.hasCoord())
|
||||||
return location.coord;
|
return location.coord;
|
||||||
|
|
||||||
if (location.hasId()) {
|
|
||||||
final Point point = pointFromStationDb(location.id);
|
|
||||||
if (point != null)
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallback kludge: search db by name
|
|
||||||
if (location.name != null) {
|
|
||||||
final Point point = pointFromStationDb(location.place, location.name);
|
|
||||||
if (point != null)
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,25 +234,6 @@ public class NearestFavoriteStationWidgetService extends JobIntentService {
|
||||||
final NetworkId networkId = NetworkId.valueOf(network);
|
final NetworkId networkId = NetworkId.valueOf(network);
|
||||||
NetworkProviderFactory.provider(networkId); // check if existent
|
NetworkProviderFactory.provider(networkId); // check if existent
|
||||||
|
|
||||||
final Cursor stationCursor = contentResolver.query(
|
|
||||||
NetworkContentProvider.CONTENT_URI.buildUpon().appendPath(networkId.name()).build(), null,
|
|
||||||
NetworkContentProvider.KEY_ID + "=?", new String[] { stationId }, null);
|
|
||||||
if (stationCursor != null) {
|
|
||||||
if (stationCursor.moveToFirst()) {
|
|
||||||
final int placeCol = stationCursor.getColumnIndex(NetworkContentProvider.KEY_PLACE);
|
|
||||||
final int nameCol = stationCursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_NAME);
|
|
||||||
final int latCol = stationCursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LAT);
|
|
||||||
final int lonCol = stationCursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LON);
|
|
||||||
|
|
||||||
if (placeCol != -1)
|
|
||||||
stationPlace = stationCursor.getString(placeCol);
|
|
||||||
stationName = stationCursor.getString(nameCol);
|
|
||||||
stationPoint = Point.from1E6(stationCursor.getInt(latCol), stationCursor.getInt(lonCol));
|
|
||||||
}
|
|
||||||
|
|
||||||
stationCursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stationPoint.getLatAsDouble() > 0 || stationPoint.getLonAsDouble() > 0) {
|
if (stationPoint.getLatAsDouble() > 0 || stationPoint.getLonAsDouble() > 0) {
|
||||||
final float[] distanceBetweenResults = new float[1];
|
final float[] distanceBetweenResults = new float[1];
|
||||||
android.location.Location.distanceBetween(here.getLatitude(), here.getLongitude(),
|
android.location.Location.distanceBetween(here.getLatitude(), here.getLongitude(),
|
||||||
|
|
|
@ -17,208 +17,12 @@
|
||||||
|
|
||||||
package de.schildbach.oeffi.stations;
|
package de.schildbach.oeffi.stations;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
|
||||||
|
|
||||||
import de.schildbach.oeffi.Application;
|
|
||||||
import de.schildbach.oeffi.Constants;
|
|
||||||
import de.schildbach.oeffi.util.Downloader;
|
|
||||||
import de.schildbach.pte.NetworkId;
|
import de.schildbach.pte.NetworkId;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import java.util.Locale;
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.DatabaseUtils;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.net.Uri;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
|
|
||||||
public final class NetworkContentProvider extends ContentProvider {
|
|
||||||
public static final Uri CONTENT_URI = Uri.parse("content://de.schildbach.oeffi.networks");
|
|
||||||
|
|
||||||
private static final String DATABASE_TABLE = "stations";
|
|
||||||
|
|
||||||
public static final String KEY_ID = "_id";
|
|
||||||
public static final String KEY_LOCAL_ID = "local_id"; // optional!
|
|
||||||
public static final String KEY_PLACE = "place"; // optional!
|
|
||||||
public static final String KEY_NAME = "name";
|
|
||||||
public static final String KEY_LAT = "lat";
|
|
||||||
public static final String KEY_LON = "lon";
|
|
||||||
public static final String KEY_PRODUCTS = "products"; // optional!
|
|
||||||
public static final String KEY_LINES = "lines";
|
|
||||||
|
|
||||||
public static final String QUERY_PARAM_Q = "q";
|
|
||||||
|
|
||||||
private Application application;
|
|
||||||
private Downloader downloader;
|
|
||||||
private final List<SQLiteDatabase> databasesToClose = new LinkedList<>();
|
|
||||||
private static final int NUM_DATABASES_TO_KEEP = 4;
|
|
||||||
|
|
||||||
private static Pattern PATTERN_Q_ID = Pattern.compile("\\d+");
|
|
||||||
|
|
||||||
|
public class NetworkContentProvider {
|
||||||
public static String dbName(final NetworkId networkId) {
|
public static String dbName(final NetworkId networkId) {
|
||||||
return networkId.name().toLowerCase(Locale.ENGLISH) + ".db";
|
return networkId.name().toLowerCase(Locale.ENGLISH) + ".db";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HttpUrl downloadUrl(final NetworkId networkId) {
|
|
||||||
return Constants.STATIONS_BASE_URL.newBuilder()
|
|
||||||
.addPathSegment(networkId.name().toLowerCase(Locale.ENGLISH) + ".db.bz2").build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(NetworkContentProvider.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreate() {
|
|
||||||
this.application = (Application) getContext();
|
|
||||||
downloader = new Downloader(application.getCacheDir());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void shutdown() {
|
|
||||||
for (final Iterator<SQLiteDatabase> i = databasesToClose.iterator(); i.hasNext();) {
|
|
||||||
i.next().close();
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized Cursor query(final Uri uri, final String[] projection, final String _selection,
|
|
||||||
final String[] _selectionArgs, final String sortOrder) {
|
|
||||||
if (databasesToClose.size() >= NUM_DATABASES_TO_KEEP)
|
|
||||||
databasesToClose.remove(0).close();
|
|
||||||
|
|
||||||
final NetworkId networkId = NetworkId.valueOf(uri.getPathSegments().get(0));
|
|
||||||
final File dbFile = new File(getContext().getFilesDir(), dbName(networkId));
|
|
||||||
final HttpUrl remoteUrl = downloadUrl(networkId);
|
|
||||||
final ListenableFuture<Integer> download = downloader.download(application.okHttpClient(), remoteUrl, dbFile, true, null);
|
|
||||||
Futures.addCallback(download, new FutureCallback<Integer>() {
|
|
||||||
public void onSuccess(final @Nullable Integer status) {
|
|
||||||
if (status == HttpURLConnection.HTTP_OK)
|
|
||||||
getContext().getContentResolver().notifyChange(uri, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
}
|
|
||||||
}, MoreExecutors.directExecutor());
|
|
||||||
|
|
||||||
if (!dbFile.exists())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
final String lat = uri.getQueryParameter("lat");
|
|
||||||
final String lon = uri.getQueryParameter("lon");
|
|
||||||
final String ids = uri.getQueryParameter("ids");
|
|
||||||
final String place = uri.getQueryParameter(KEY_PLACE);
|
|
||||||
final String name = uri.getQueryParameter(KEY_NAME);
|
|
||||||
final String q = uri.getQueryParameter(QUERY_PARAM_Q);
|
|
||||||
final String devLat = "100000"; // 0.1 degrees
|
|
||||||
final String devLon = "200000"; // 0.2 degrees
|
|
||||||
|
|
||||||
final SQLiteDatabase db = SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);
|
|
||||||
|
|
||||||
// test if database contains optional columns
|
|
||||||
final Cursor testCursor = db.query(DATABASE_TABLE, null, null, null, null, null, null, "0");
|
|
||||||
final boolean hasLocalId = testCursor.getColumnIndex(NetworkContentProvider.KEY_LOCAL_ID) != -1;
|
|
||||||
final boolean hasPlace = testCursor.getColumnIndex(NetworkContentProvider.KEY_PLACE) != -1;
|
|
||||||
final boolean hasProducts = testCursor.getColumnIndex(NetworkContentProvider.KEY_PRODUCTS) != -1;
|
|
||||||
testCursor.close();
|
|
||||||
|
|
||||||
String selection = null;
|
|
||||||
List<String> selectionArgs = new ArrayList<>();
|
|
||||||
|
|
||||||
if (lat != null || lon != null) {
|
|
||||||
selection = "(" + KEY_LAT + ">?-" + devLat + " AND " + KEY_LAT + "<?+" + devLat + " AND " //
|
|
||||||
+ KEY_LON + ">?-" + devLon + " AND " + KEY_LON + "<?+" + devLon + ")";
|
|
||||||
selectionArgs.addAll(Arrays.asList(lat, lat, lon, lon));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (place != null && hasPlace) {
|
|
||||||
selection = (selection != null ? selection + " AND " : "") + KEY_PLACE
|
|
||||||
+ (!place.isEmpty() ? "=?" : " IS NULL");
|
|
||||||
if (!place.isEmpty())
|
|
||||||
selectionArgs.add(place);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name != null) {
|
|
||||||
selection = (selection != null ? selection + " AND " : "") + KEY_NAME
|
|
||||||
+ (!name.isEmpty() ? "=?" : " IS NULL");
|
|
||||||
if (!name.isEmpty())
|
|
||||||
selectionArgs.add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ids != null && ids.length() > 0 && selection != null) {
|
|
||||||
final StringBuilder escapedIds = new StringBuilder();
|
|
||||||
for (final String id : ids.split(",")) {
|
|
||||||
DatabaseUtils.appendEscapedSQLString(escapedIds, id);
|
|
||||||
escapedIds.append(',');
|
|
||||||
}
|
|
||||||
if (escapedIds.length() > 0)
|
|
||||||
escapedIds.setLength(escapedIds.length() - 1);
|
|
||||||
|
|
||||||
selection = "(" + selection + ") OR " + (hasLocalId ? KEY_LOCAL_ID : KEY_ID) + " IN (" + escapedIds + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (q != null) {
|
|
||||||
final boolean maybeId = PATTERN_Q_ID.matcher(q).matches();
|
|
||||||
|
|
||||||
selection = (selection != null ? "(" + selection + ") AND " : "") + "("
|
|
||||||
+ (maybeId ? KEY_ID + " = ? OR " : "") + (hasPlace ? KEY_PLACE + " LIKE ? OR " : "") + KEY_NAME
|
|
||||||
+ " LIKE ?)";
|
|
||||||
if (maybeId)
|
|
||||||
selectionArgs.add(q);
|
|
||||||
if (hasPlace)
|
|
||||||
selectionArgs.add("%" + q + "%");
|
|
||||||
selectionArgs.add("%" + q + "%");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_selection != null) {
|
|
||||||
selection = (selection != null ? "(" + selection + ") AND " : "") //
|
|
||||||
+ "(" + _selection + ")";
|
|
||||||
if (_selectionArgs != null)
|
|
||||||
selectionArgs.addAll(Arrays.asList(_selectionArgs));
|
|
||||||
}
|
|
||||||
|
|
||||||
final Cursor result = db.query(DATABASE_TABLE, projection, selection, selectionArgs.toArray(new String[0]),
|
|
||||||
null, null, sortOrder);
|
|
||||||
result.setNotificationUri(getContext().getContentResolver(), uri);
|
|
||||||
|
|
||||||
databasesToClose.add(db);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType(Uri uri) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Uri insert(Uri uri, ContentValues values) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -37,7 +36,6 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Strings;
|
|
||||||
|
|
||||||
import de.schildbach.oeffi.Constants;
|
import de.schildbach.oeffi.Constants;
|
||||||
import de.schildbach.oeffi.MyActionBar;
|
import de.schildbach.oeffi.MyActionBar;
|
||||||
|
@ -57,11 +55,8 @@ import de.schildbach.pte.dto.Line;
|
||||||
import de.schildbach.pte.dto.LineDestination;
|
import de.schildbach.pte.dto.LineDestination;
|
||||||
import de.schildbach.pte.dto.Location;
|
import de.schildbach.pte.dto.Location;
|
||||||
import de.schildbach.pte.dto.LocationType;
|
import de.schildbach.pte.dto.LocationType;
|
||||||
import de.schildbach.pte.dto.Point;
|
|
||||||
import de.schildbach.pte.dto.Product;
|
|
||||||
import de.schildbach.pte.dto.QueryDeparturesResult;
|
import de.schildbach.pte.dto.QueryDeparturesResult;
|
||||||
import de.schildbach.pte.dto.StationDepartures;
|
import de.schildbach.pte.dto.StationDepartures;
|
||||||
import de.schildbach.pte.dto.Style;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -69,7 +64,6 @@ import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -122,8 +116,6 @@ public class StationDetailsActivity extends OeffiActivity implements StationsAwa
|
||||||
private Integer selectedFavState = null;
|
private Integer selectedFavState = null;
|
||||||
@Nullable
|
@Nullable
|
||||||
private LinkedHashMap<Line, List<Location>> selectedLines = null;
|
private LinkedHashMap<Line, List<Location>> selectedLines = null;
|
||||||
@Nullable
|
|
||||||
private List<Line> selectedAdditionalLines = null;
|
|
||||||
|
|
||||||
private MyActionBar actionBar;
|
private MyActionBar actionBar;
|
||||||
private ToggleImageButton favoriteButton;
|
private ToggleImageButton favoriteButton;
|
||||||
|
@ -381,68 +373,6 @@ public class StationDetailsActivity extends OeffiActivity implements StationsAwa
|
||||||
for (final StationDepartures stationDepartures : result.stationDepartures) {
|
for (final StationDepartures stationDepartures : result.stationDepartures) {
|
||||||
Location location = stationDepartures.location;
|
Location location = stationDepartures.location;
|
||||||
if (location.hasId()) {
|
if (location.hasId()) {
|
||||||
List<Line> additionalLines = null;
|
|
||||||
|
|
||||||
final Cursor cursor = getContentResolver().query(
|
|
||||||
NetworkContentProvider.CONTENT_URI.buildUpon()
|
|
||||||
.appendPath(selectedNetwork.name()).build(),
|
|
||||||
null, NetworkContentProvider.KEY_ID + "=?", new String[] { location.id },
|
|
||||||
null);
|
|
||||||
if (cursor != null) {
|
|
||||||
if (cursor.moveToFirst()) {
|
|
||||||
final int placeCol = cursor
|
|
||||||
.getColumnIndex(NetworkContentProvider.KEY_PLACE);
|
|
||||||
final int nameCol = cursor
|
|
||||||
.getColumnIndexOrThrow(NetworkContentProvider.KEY_NAME);
|
|
||||||
final int latCol = cursor
|
|
||||||
.getColumnIndexOrThrow(NetworkContentProvider.KEY_LAT);
|
|
||||||
final int lonCol = cursor
|
|
||||||
.getColumnIndexOrThrow(NetworkContentProvider.KEY_LON);
|
|
||||||
final int productsCol = cursor
|
|
||||||
.getColumnIndex(NetworkContentProvider.KEY_PRODUCTS);
|
|
||||||
final int linesCol = cursor
|
|
||||||
.getColumnIndexOrThrow(NetworkContentProvider.KEY_LINES);
|
|
||||||
|
|
||||||
final Point coord = Point.from1E6(cursor.getInt(latCol),
|
|
||||||
cursor.getInt(lonCol));
|
|
||||||
final String place = placeCol != -1 ? cursor.getString(placeCol)
|
|
||||||
: selectedStation.place;
|
|
||||||
final String name = cursor.getString(nameCol);
|
|
||||||
final Set<Product> products;
|
|
||||||
if (productsCol != -1 && !cursor.isNull(productsCol))
|
|
||||||
products = Product
|
|
||||||
.fromCodes(cursor.getString(productsCol).toCharArray());
|
|
||||||
else
|
|
||||||
products = null;
|
|
||||||
location = new Location(LocationType.STATION, location.id, coord, place,
|
|
||||||
name, products);
|
|
||||||
|
|
||||||
final String[] additionalLinesArray = cursor.getString(linesCol).split(",");
|
|
||||||
additionalLines = new ArrayList<>(additionalLinesArray.length);
|
|
||||||
l: for (final String additionalLineStr : additionalLinesArray) {
|
|
||||||
if (!additionalLineStr.isEmpty()) {
|
|
||||||
final Product additionalLineProduct = Product
|
|
||||||
.fromCode(additionalLineStr.charAt(0));
|
|
||||||
final String additionalLineLabel = Strings
|
|
||||||
.emptyToNull(additionalLineStr.substring(1));
|
|
||||||
final Line additionalLine = new Line(null, null,
|
|
||||||
additionalLineProduct, additionalLineLabel);
|
|
||||||
final List<LineDestination> lineDestinations = stationDepartures.lines;
|
|
||||||
if (lineDestinations != null)
|
|
||||||
for (final LineDestination lineDestination : lineDestinations)
|
|
||||||
if (lineDestination.line.equals(additionalLine))
|
|
||||||
continue l;
|
|
||||||
final Style style = networkProvider.lineStyle(null,
|
|
||||||
additionalLine.product, additionalLine.label);
|
|
||||||
additionalLines.add(new Line(null, null, additionalLine.product,
|
|
||||||
additionalLine.label, style));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
Station station = findStation(location.id);
|
Station station = findStation(location.id);
|
||||||
if (station == null) {
|
if (station == null) {
|
||||||
station = new Station(selectedNetwork, location);
|
station = new Station(selectedNetwork, location);
|
||||||
|
@ -455,7 +385,6 @@ public class StationDetailsActivity extends OeffiActivity implements StationsAwa
|
||||||
if (location.equals(selectedStation)) {
|
if (location.equals(selectedStation)) {
|
||||||
selectedDepartures = stationDepartures.departures;
|
selectedDepartures = stationDepartures.departures;
|
||||||
selectedLines = groupDestinationsByLine(stationDepartures.lines);
|
selectedLines = groupDestinationsByLine(stationDepartures.lines);
|
||||||
selectedAdditionalLines = additionalLines;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,53 +439,6 @@ public class StationDetailsActivity extends OeffiActivity implements StationsAwa
|
||||||
selectedStation = station.location;
|
selectedStation = station.location;
|
||||||
selectedDepartures = station.departures;
|
selectedDepartures = station.departures;
|
||||||
selectedLines = groupDestinationsByLine(station.getLines());
|
selectedLines = groupDestinationsByLine(station.getLines());
|
||||||
selectedAdditionalLines = null;
|
|
||||||
|
|
||||||
final Cursor stationCursor = getContentResolver().query(
|
|
||||||
NetworkContentProvider.CONTENT_URI.buildUpon().appendPath(selectedNetwork.name()).build(), null,
|
|
||||||
NetworkContentProvider.KEY_ID + "=?", new String[] { selectedStation.id }, null);
|
|
||||||
if (stationCursor != null) {
|
|
||||||
if (stationCursor.moveToFirst()) {
|
|
||||||
final int placeCol = stationCursor.getColumnIndex(NetworkContentProvider.KEY_PLACE);
|
|
||||||
final int nameCol = stationCursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_NAME);
|
|
||||||
final int latCol = stationCursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LAT);
|
|
||||||
final int lonCol = stationCursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LON);
|
|
||||||
final int productsCol = stationCursor.getColumnIndex(NetworkContentProvider.KEY_PRODUCTS);
|
|
||||||
final int linesCol = stationCursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LINES);
|
|
||||||
|
|
||||||
final Point coord = Point.from1E6(stationCursor.getInt(latCol), stationCursor.getInt(lonCol));
|
|
||||||
final String place = placeCol != -1 ? stationCursor.getString(placeCol) : selectedStation.place;
|
|
||||||
final String name = stationCursor.getString(nameCol);
|
|
||||||
final Set<Product> products;
|
|
||||||
if (productsCol != -1 && !stationCursor.isNull(productsCol))
|
|
||||||
products = Product.fromCodes(stationCursor.getString(productsCol).toCharArray());
|
|
||||||
else
|
|
||||||
products = null;
|
|
||||||
selectedStation = new Location(LocationType.STATION, selectedStation.id, coord, place, name, products);
|
|
||||||
|
|
||||||
final NetworkProvider networkProvider = NetworkProviderFactory.provider(selectedNetwork);
|
|
||||||
|
|
||||||
final String[] additionalLinesArray = stationCursor.getString(linesCol).split(",");
|
|
||||||
final List<Line> additionalLines = new ArrayList<>(additionalLinesArray.length);
|
|
||||||
l: for (final String additionalLineStr : additionalLinesArray) {
|
|
||||||
if (!additionalLineStr.isEmpty()) {
|
|
||||||
final Product additionalLineProduct = Product.fromCode(additionalLineStr.charAt(0));
|
|
||||||
final String additionalLineLabel = Strings.emptyToNull(additionalLineStr.substring(1));
|
|
||||||
final Line additionalLine = new Line(null, null, additionalLineProduct, additionalLineLabel);
|
|
||||||
final List<LineDestination> lineDestinations = station.getLines();
|
|
||||||
if (lineDestinations != null)
|
|
||||||
for (final LineDestination line : lineDestinations)
|
|
||||||
if (line.line.equals(additionalLine))
|
|
||||||
continue l;
|
|
||||||
additionalLines.add(new Line(null, null, additionalLine.product, additionalLine.label,
|
|
||||||
networkProvider.lineStyle(null, additionalLine.product, additionalLine.label)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selectedAdditionalLines = additionalLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
stationCursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedFavState = FavoriteStationsProvider.favState(getContentResolver(), selectedNetwork, selectedStation);
|
selectedFavState = FavoriteStationsProvider.favState(getContentResolver(), selectedNetwork, selectedStation);
|
||||||
|
|
||||||
|
@ -647,7 +529,7 @@ public class StationDetailsActivity extends OeffiActivity implements StationsAwa
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
|
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
|
||||||
if (holder instanceof HeaderViewHolder) {
|
if (holder instanceof HeaderViewHolder) {
|
||||||
((HeaderViewHolder) holder).bind(selectedStation, selectedLines, selectedAdditionalLines);
|
((HeaderViewHolder) holder).bind(selectedStation, selectedLines, null);
|
||||||
} else {
|
} else {
|
||||||
final Departure departure = getItem(position);
|
final Departure departure = getItem(position);
|
||||||
((DepartureViewHolder) holder).bind(selectedNetwork, departure);
|
((DepartureViewHolder) holder).bind(selectedNetwork, departure);
|
||||||
|
|
|
@ -33,15 +33,12 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.osmdroid.util.BoundingBox;
|
import org.osmdroid.util.BoundingBox;
|
||||||
import org.osmdroid.util.GeoPoint;
|
import org.osmdroid.util.GeoPoint;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.google.common.collect.ComparisonChain;
|
import com.google.common.collect.ComparisonChain;
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
|
@ -72,11 +69,11 @@ import de.schildbach.pte.dto.Line;
|
||||||
import de.schildbach.pte.dto.LineDestination;
|
import de.schildbach.pte.dto.LineDestination;
|
||||||
import de.schildbach.pte.dto.Location;
|
import de.schildbach.pte.dto.Location;
|
||||||
import de.schildbach.pte.dto.LocationType;
|
import de.schildbach.pte.dto.LocationType;
|
||||||
|
import de.schildbach.pte.dto.NearbyLocationsResult;
|
||||||
import de.schildbach.pte.dto.Point;
|
import de.schildbach.pte.dto.Point;
|
||||||
import de.schildbach.pte.dto.Product;
|
import de.schildbach.pte.dto.Product;
|
||||||
import de.schildbach.pte.dto.QueryDeparturesResult;
|
import de.schildbach.pte.dto.QueryDeparturesResult;
|
||||||
import de.schildbach.pte.dto.StationDepartures;
|
import de.schildbach.pte.dto.StationDepartures;
|
||||||
import de.schildbach.pte.dto.Style;
|
|
||||||
import de.schildbach.pte.dto.SuggestLocationsResult;
|
import de.schildbach.pte.dto.SuggestLocationsResult;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
@ -90,8 +87,6 @@ import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
@ -105,7 +100,6 @@ import android.location.LocationManager;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.Uri.Builder;
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
@ -449,9 +443,6 @@ public class StationsActivity extends OeffiMainActivity implements StationsAware
|
||||||
if (network != null && NetworkProviderFactory.provider(network).hasCapabilities(Capability.DEPARTURES)) {
|
if (network != null && NetworkProviderFactory.provider(network).hasCapabilities(Capability.DEPARTURES)) {
|
||||||
startLocationProvider();
|
startLocationProvider();
|
||||||
|
|
||||||
// request update on content change (db loaded)
|
|
||||||
getContentResolver().registerContentObserver(NetworkContentProvider.CONTENT_URI, true, contentObserver);
|
|
||||||
|
|
||||||
// request update on orientation change
|
// request update on orientation change
|
||||||
sensorManager.registerListener(orientationListener, sensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
|
sensorManager.registerListener(orientationListener, sensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
|
||||||
sensorManager.registerListener(orientationListener, sensorMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
|
sensorManager.registerListener(orientationListener, sensorMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
|
||||||
|
@ -529,9 +520,6 @@ public class StationsActivity extends OeffiMainActivity implements StationsAware
|
||||||
// cancel update on orientation change
|
// cancel update on orientation change
|
||||||
sensorManager.unregisterListener(orientationListener);
|
sensorManager.unregisterListener(orientationListener);
|
||||||
|
|
||||||
// cancel content change
|
|
||||||
getContentResolver().unregisterContentObserver(contentObserver);
|
|
||||||
|
|
||||||
// cancel background thread
|
// cancel background thread
|
||||||
backgroundThread.getLooper().quit();
|
backgroundThread.getLooper().quit();
|
||||||
|
|
||||||
|
@ -755,13 +743,6 @@ public class StationsActivity extends OeffiMainActivity implements StationsAware
|
||||||
return super.onCreateDialog(id);
|
return super.onCreateDialog(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ContentObserver contentObserver = new ContentObserver(handler) {
|
|
||||||
@Override
|
|
||||||
public void onChange(final boolean selfChange) {
|
|
||||||
runOnUiThread(initStationsRunnable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final Runnable initStationsRunnable = new Runnable() {
|
private final Runnable initStationsRunnable = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (network != null) {
|
if (network != null) {
|
||||||
|
@ -792,75 +773,42 @@ public class StationsActivity extends OeffiMainActivity implements StationsAware
|
||||||
updateGUI();
|
updateGUI();
|
||||||
});
|
});
|
||||||
|
|
||||||
final Builder uriBuilder = NetworkContentProvider.CONTENT_URI.buildUpon();
|
final NetworkProvider networkProvider = NetworkProviderFactory.provider(network);
|
||||||
uriBuilder.appendPath(network.name());
|
try {
|
||||||
uriBuilder.appendQueryParameter("lat", Integer.toString(referenceLocation.getLatAs1E6()));
|
final NearbyLocationsResult result =
|
||||||
uriBuilder.appendQueryParameter("lon", Integer.toString(referenceLocation.getLonAs1E6()));
|
networkProvider.queryNearbyLocations(EnumSet.of(LocationType.STATION),
|
||||||
uriBuilder.appendQueryParameter("ids", favoriteIds.toString());
|
referenceLocation, 0, 0);
|
||||||
final Cursor cursor = getContentResolver().query(uriBuilder.build(), null, null, null, null);
|
if (result.status == NearbyLocationsResult.Status.OK) {
|
||||||
|
log.info("Got {}", result.toShortString());
|
||||||
|
|
||||||
if (cursor != null) {
|
final List<Station> freshStations = new ArrayList<>(result.locations.size());
|
||||||
final int nativeIdColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_ID);
|
final float[] distanceBetweenResults = new float[2];
|
||||||
final int localIdColumnIndex = cursor.getColumnIndex(NetworkContentProvider.KEY_LOCAL_ID);
|
|
||||||
final int placeColumnIndex = cursor.getColumnIndex(NetworkContentProvider.KEY_PLACE);
|
|
||||||
final int nameColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_NAME);
|
|
||||||
final int latColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LAT);
|
|
||||||
final int lonColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LON);
|
|
||||||
final int productsColumnIndex = cursor.getColumnIndex(NetworkContentProvider.KEY_PRODUCTS);
|
|
||||||
final int linesColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LINES);
|
|
||||||
|
|
||||||
final List<Station> freshStations = new ArrayList<>(cursor.getCount());
|
for (final Location location : result.locations) {
|
||||||
|
if (location.type == LocationType.STATION) {
|
||||||
final float[] distanceBetweenResults = new float[2];
|
final Station station = new Station(network, location, null);
|
||||||
|
if (deviceLocation != null) {
|
||||||
final NetworkProvider networkProvider = NetworkProviderFactory.provider(network);
|
android.location.Location.distanceBetween(referenceLocation.getLatAsDouble(),
|
||||||
|
referenceLocation.getLonAsDouble(), location.getLatAsDouble(),
|
||||||
while (cursor.moveToNext()) {
|
location.getLonAsDouble(), distanceBetweenResults);
|
||||||
final List<LineDestination> lineDestinations = new LinkedList<>();
|
station.setDistanceAndBearing(distanceBetweenResults[0],
|
||||||
for (final String lineStr : cursor.getString(linesColumnIndex).split(",")) {
|
distanceBetweenResults[1]);
|
||||||
if (!lineStr.isEmpty()) {
|
}
|
||||||
final Product product = Product.fromCode(lineStr.charAt(0));
|
freshStations.add(station);
|
||||||
final String label = Strings.emptyToNull(lineStr.substring(1));
|
|
||||||
// FIXME don't access networkProvider
|
|
||||||
// from thread
|
|
||||||
final Style style = networkProvider.lineStyle(null, product, label);
|
|
||||||
lineDestinations.add(
|
|
||||||
new LineDestination(new Line(null, null, product, label, style), null));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final String id = localIdColumnIndex != -1 ? cursor.getString(localIdColumnIndex)
|
runOnUiThread(() -> mergeIntoStations(freshStations, true));
|
||||||
: cursor.getString(nativeIdColumnIndex);
|
|
||||||
final String place = placeColumnIndex != -1 ? cursor.getString(placeColumnIndex) : null;
|
|
||||||
final String name = cursor.getString(nameColumnIndex);
|
|
||||||
final Point coord = Point.from1E6(cursor.getInt(latColumnIndex),
|
|
||||||
cursor.getInt(lonColumnIndex));
|
|
||||||
final Set<Product> products;
|
|
||||||
if (productsColumnIndex != -1 && !cursor.isNull(productsColumnIndex))
|
|
||||||
products = Product.fromCodes(cursor.getString(productsColumnIndex).toCharArray());
|
|
||||||
else
|
|
||||||
products = null;
|
|
||||||
final Station station = new Station(network, new Location(
|
|
||||||
LocationType.STATION, id, coord, place, name, products), lineDestinations);
|
|
||||||
if (deviceLocation != null) {
|
|
||||||
android.location.Location.distanceBetween(referenceLocation.getLatAsDouble(),
|
|
||||||
referenceLocation.getLonAsDouble(), coord.getLatAsDouble(), coord.getLonAsDouble(),
|
|
||||||
distanceBetweenResults);
|
|
||||||
station.setDistanceAndBearing(distanceBetweenResults[0], distanceBetweenResults[1]);
|
|
||||||
}
|
|
||||||
freshStations.add(station);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.close();
|
runOnUiThread(() -> {
|
||||||
|
actionBar.stopProgress();
|
||||||
runOnUiThread(() -> mergeIntoStations(freshStations, true));
|
loading = false;
|
||||||
|
updateGUI();
|
||||||
|
});
|
||||||
|
} catch (final IOException x) {
|
||||||
|
log.info("IO problem while querying for nearby locations to " + referenceLocation, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
|
||||||
actionBar.stopProgress();
|
|
||||||
loading = false;
|
|
||||||
updateGUI();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1524,69 +1472,19 @@ public class StationsActivity extends OeffiMainActivity implements StationsAware
|
||||||
|
|
||||||
final String query = params[0];
|
final String query = params[0];
|
||||||
|
|
||||||
final Builder uriBuilder = NetworkContentProvider.CONTENT_URI.buildUpon();
|
|
||||||
uriBuilder.appendPath(network.name());
|
|
||||||
uriBuilder.appendQueryParameter(NetworkContentProvider.QUERY_PARAM_Q, query);
|
|
||||||
|
|
||||||
final Cursor cursor = getContentResolver().query(uriBuilder.build(), null, null, null,
|
|
||||||
NetworkContentProvider.KEY_NAME);
|
|
||||||
final Matcher mQuery = Pattern.compile("(^|[ -/\\(])" + query, Pattern.CASE_INSENSITIVE).matcher("");
|
|
||||||
final NetworkProvider networkProvider = NetworkProviderFactory.provider(network);
|
final NetworkProvider networkProvider = NetworkProviderFactory.provider(network);
|
||||||
|
|
||||||
final List<Station> stations = new LinkedList<>();
|
final List<Station> stations = new LinkedList<>();
|
||||||
if (cursor != null) {
|
try {
|
||||||
final int nativeIdColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_ID);
|
final SuggestLocationsResult result = networkProvider.suggestLocations(query,
|
||||||
final int localIdColumnIndex = cursor.getColumnIndex(NetworkContentProvider.KEY_LOCAL_ID);
|
EnumSet.of(LocationType.STATION), 0);
|
||||||
final int placeColumnIndex = cursor.getColumnIndex(NetworkContentProvider.KEY_PLACE);
|
if (result.status == SuggestLocationsResult.Status.OK)
|
||||||
final int nameColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_NAME);
|
log.info("Got {}", result.toShortString());
|
||||||
final int latColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LAT);
|
for (final Location l : result.getLocations())
|
||||||
final int lonColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LON);
|
if (l.type == LocationType.STATION)
|
||||||
final int productsColumnIndex = cursor.getColumnIndex(NetworkContentProvider.KEY_PRODUCTS);
|
stations.add(new Station(network, l));
|
||||||
final int linesColumnIndex = cursor.getColumnIndexOrThrow(NetworkContentProvider.KEY_LINES);
|
} catch (final IOException x) {
|
||||||
|
x.printStackTrace();
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
final String id = localIdColumnIndex != -1 ? cursor.getString(localIdColumnIndex)
|
|
||||||
: cursor.getString(nativeIdColumnIndex);
|
|
||||||
final String place = placeColumnIndex != -1 ? cursor.getString(placeColumnIndex) : null;
|
|
||||||
final String name = cursor.getString(nameColumnIndex);
|
|
||||||
|
|
||||||
if (id.equals(query) || (place != null && mQuery.reset(place).find())
|
|
||||||
|| mQuery.reset(name).find()) {
|
|
||||||
final int lat = cursor.getInt(latColumnIndex);
|
|
||||||
final int lon = cursor.getInt(lonColumnIndex);
|
|
||||||
final Point coord = Point.from1E6(lat, lon);
|
|
||||||
final Set<Product> products;
|
|
||||||
if (productsColumnIndex != -1 && !cursor.isNull(productsColumnIndex))
|
|
||||||
products = Product.fromCodes(cursor.getString(productsColumnIndex).toCharArray());
|
|
||||||
else
|
|
||||||
products = null;
|
|
||||||
final List<LineDestination> lineDestinations = new LinkedList<>();
|
|
||||||
for (final String lineStr : cursor.getString(linesColumnIndex).split(",")) {
|
|
||||||
if (!lineStr.isEmpty()) {
|
|
||||||
final Product product = Product.fromCode(lineStr.charAt(0));
|
|
||||||
final String label = Strings.emptyToNull(lineStr.substring(1));
|
|
||||||
final Style style = networkProvider.lineStyle(null, product, label);
|
|
||||||
lineDestinations
|
|
||||||
.add(new LineDestination(new Line(null, null, product, label, style), null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final Location location = new Location(LocationType.STATION, id, coord, place, name, products);
|
|
||||||
stations.add(new Station(network, location, lineDestinations));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.close();
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
final SuggestLocationsResult result = networkProvider.suggestLocations(query,
|
|
||||||
EnumSet.of(LocationType.STATION), 0);
|
|
||||||
if (result.status == SuggestLocationsResult.Status.OK)
|
|
||||||
for (final Location l : result.getLocations())
|
|
||||||
if (l.type == LocationType.STATION)
|
|
||||||
stations.add(new Station(network, l));
|
|
||||||
} catch (final IOException x) {
|
|
||||||
x.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return stations;
|
return stations;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue