diff --git a/src/it/reyboz/bustorino/ActivityMap.java b/src/it/reyboz/bustorino/ActivityMap.java --- a/src/it/reyboz/bustorino/ActivityMap.java +++ b/src/it/reyboz/bustorino/ActivityMap.java @@ -33,6 +33,7 @@ import android.support.v7.preference.PreferenceManager; import android.widget.Toast; +import it.reyboz.bustorino.middleware.NextGenDB; import org.osmdroid.api.IMapController; import org.osmdroid.config.Configuration; import org.osmdroid.events.DelayedMapListener; @@ -321,10 +322,15 @@ double lngTo = bb.getLonEast(); // get the stops located in those coordinates + /* StopsDB stopsDB = new StopsDB(ctx); stopsDB.openIfNeeded(); Stop[] stops = stopsDB.queryAllInsideMapView(latFrom, latTo, lngFrom, lngTo); stopsDB.closeIfNeeded(); + */ + + NextGenDB dbHelper = new NextGenDB(ctx); + Stop[] stops = dbHelper.queryAllInsideMapView(latFrom, latTo, lngFrom, lngTo); // add new markers of those stops for (Stop stop : stops) { diff --git a/src/it/reyboz/bustorino/backend/Route.java b/src/it/reyboz/bustorino/backend/Route.java --- a/src/it/reyboz/bustorino/backend/Route.java +++ b/src/it/reyboz/bustorino/backend/Route.java @@ -164,6 +164,19 @@ public void addPassaggio(int hour, int minutes, boolean realtime, Passaggio.Source source) { this.passaggi.add(new Passaggio(hour, minutes, realtime, source)); } + + public static Route.Type getTypeFromSymbol(String route) { + switch (route) { + case "M": + return Route.Type.METRO; + case "T": + return Route.Type.RAILWAY; + } + + // default with case "B" + return Route.Type.BUS; + } + private String parseDestinazione(String direzione){ if(direzione==null) return null; //trial to add space to the parenthesis @@ -229,6 +242,7 @@ return sb.toString(); } + @Override public int compareTo(@NonNull Route other) { int res; diff --git a/src/it/reyboz/bustorino/fragments/FragmentHelper.java b/src/it/reyboz/bustorino/fragments/FragmentHelper.java --- a/src/it/reyboz/bustorino/fragments/FragmentHelper.java +++ b/src/it/reyboz/bustorino/fragments/FragmentHelper.java @@ -59,7 +59,7 @@ this.swipeRefID = swipeRefID; this.primaryFrameLayout = primaryFrameLayout; this.secondaryFrameLayout = secondaryFrameLayout; - newDBHelper = NextGenDB.getInstance(act.getApplicationContext()); + newDBHelper = new NextGenDB(act.getApplicationContext()); } /** diff --git a/src/it/reyboz/bustorino/middleware/AppDataProvider.java b/src/it/reyboz/bustorino/middleware/AppDataProvider.java --- a/src/it/reyboz/bustorino/middleware/AppDataProvider.java +++ b/src/it/reyboz/bustorino/middleware/AppDataProvider.java @@ -183,7 +183,7 @@ @Override public boolean onCreate() { con = getContext(); - appDBHelper = NextGenDB.getInstance(getContext()); + appDBHelper = new NextGenDB(getContext()); udbhelper = new UserDB(getContext()); if(con!=null) { preferences = new DBStatusManager(con,null); diff --git a/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java b/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java --- a/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java +++ b/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java @@ -138,7 +138,7 @@ if(!setDBUpdatingFlag(true)) return false; //If the commit to the SharedPreferences didn't succeed, simply stop updating the database - final NextGenDB dbHelp = NextGenDB.getInstance(getApplicationContext()); + final NextGenDB dbHelp = new NextGenDB(getApplicationContext()); final SQLiteDatabase db = dbHelp.getWritableDatabase(); //Empty the needed tables db.beginTransaction(); diff --git a/src/it/reyboz/bustorino/middleware/NextGenDB.java b/src/it/reyboz/bustorino/middleware/NextGenDB.java --- a/src/it/reyboz/bustorino/middleware/NextGenDB.java +++ b/src/it/reyboz/bustorino/middleware/NextGenDB.java @@ -20,21 +20,29 @@ import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; +import android.database.Cursor; import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; +import android.support.annotation.Nullable; import android.util.Log; import it.reyboz.bustorino.R; +import it.reyboz.bustorino.backend.Route; +import it.reyboz.bustorino.backend.Stop; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import static it.reyboz.bustorino.middleware.NextGenDB.Contract.*; public class NextGenDB extends SQLiteOpenHelper{ public static final String DATABASE_NAME = "bustodatabase.db"; public static final int DATABASE_VERSION = 2; - //Singleton instance - private static volatile NextGenDB instance = null; + public static final String DEBUG_TAG = "NextGenDB-BusTO"; + //NO Singleton instance + //private static volatile NextGenDB instance = null; //Some generating Strings private static final String SQL_CREATE_LINES_TABLE="CREATE TABLE "+Contract.LinesTable.TABLE_NAME+" ("+ Contract.LinesTable._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+ Contract.LinesTable.COLUMN_NAME +" TEXT, "+ @@ -71,9 +79,18 @@ Contract.StopsTable.COL_LOCATION+" TEXT, "+Contract.StopsTable.COL_PLACE+" TEXT, "+ Contract.StopsTable.COL_LINES_STOPPING +" TEXT )"; + private static final String[] QUERY_COLUMN_stops_all = { + StopsTable.COL_ID, StopsTable.COL_NAME, StopsTable.COL_LOCATION, + StopsTable.COL_TYPE, StopsTable.COL_LAT, StopsTable.COL_LONG, StopsTable.COL_LINES_STOPPING}; + + private static final String QUERY_WHERE_LAT_AND_LNG_IN_RANGE = StopsTable.COL_LAT + " >= ? AND " + + StopsTable.COL_LAT + " <= ? AND "+ StopsTable.COL_LONG + + " >= ? AND "+ StopsTable.COL_LONG + " <= ?"; + + private Context appContext; - private NextGenDB(Context context) { + public NextGenDB(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); appContext = context.getApplicationContext(); } @@ -81,9 +98,9 @@ /** * Lazy initialization singleton getter, thread-safe with double checked locking * from https://en.wikipedia.org/wiki/Singleton_pattern - * @param context needed context * @return the instance */ + /* public static NextGenDB getInstance(Context context){ if(instance==null){ synchronized (NextGenDB.class){ @@ -93,7 +110,7 @@ } } return instance; - } + }*/ @Override public void onCreate(SQLiteDatabase db) { @@ -133,6 +150,7 @@ db.execSQL("PRAGMA foreign_keys=ON"); } + public static String getSqlCreateStopsTable(String tableName){ return "CREATE TABLE "+tableName+" ("+ @@ -142,6 +160,82 @@ Contract.StopsTable.COL_LINES_STOPPING +" TEXT )"; } + /** + * Query some bus stops inside a map view + * + * You can obtain the coordinates from OSMDroid using something like this: + * BoundingBoxE6 bb = mMapView.getBoundingBox(); + * double latFrom = bb.getLatSouthE6() / 1E6; + * double latTo = bb.getLatNorthE6() / 1E6; + * double lngFrom = bb.getLonWestE6() / 1E6; + * double lngTo = bb.getLonEastE6() / 1E6; + */ + public synchronized Stop[] queryAllInsideMapView(double minLat, double maxLat, double minLng, double maxLng) { + Stop[] stops = new Stop[0]; + SQLiteDatabase db = this.getReadableDatabase(); + + Cursor result; + int count; + + // coordinates must be strings in the where condition + String minLatRaw = String.valueOf(minLat); + String maxLatRaw = String.valueOf(maxLat); + String minLngRaw = String.valueOf(minLng); + String maxLngRaw = String.valueOf(maxLng); + + String[] queryColumns = {}; + String stopID; + Route.Type type; + + if(db == null) { + return stops; + } + + try { + result = db.query(StopsTable.TABLE_NAME, QUERY_COLUMN_stops_all, QUERY_WHERE_LAT_AND_LNG_IN_RANGE, + new String[] {minLatRaw, maxLatRaw, minLngRaw, maxLngRaw}, + null, null, null); + + int colID = result.getColumnIndex(StopsTable.COL_ID); + int colName = result.getColumnIndex(StopsTable.COL_NAME); + int colLocation = result.getColumnIndex(StopsTable.COL_LOCATION); + int colType = result.getColumnIndex(StopsTable.COL_TYPE); + int colLat = result.getColumnIndex(StopsTable.COL_LAT); + int colLon = result.getColumnIndex(StopsTable.COL_LONG); + int colLines = result.getColumnIndex(StopsTable.COL_LINES_STOPPING); + + count = result.getCount(); + stops = new Stop[count]; + + int i = 0; + while(result.moveToNext()) { + + stopID = result.getString(colID); + type = Route.getTypeFromSymbol(result.getString(colType)); + String lines = result.getString(colLines).trim(); + + String locationSometimesEmpty = result.getString(colLocation); + if (locationSometimesEmpty!= null && locationSometimesEmpty.length() <= 0) { + locationSometimesEmpty = null; + } + + stops[i++] = new Stop(stopID, result.getString(colName), null, + locationSometimesEmpty, type, splitLinesString(lines), + result.getDouble(colLat), result.getDouble(colLon)); + } + + } catch(SQLiteException e) { + Log.e(DEBUG_TAG, "SQLiteException occurred"); + e.printStackTrace(); + return stops; + } + + result.close(); + db.close(); + + return stops; + } + /** * Insert batch content, already prepared as * @param content ContentValues array @@ -170,6 +264,10 @@ return success; } + public static List splitLinesString(String linesStr){ + return Arrays.asList(linesStr.split("\\s*,\\s*")); + } + public static final class Contract{ //Ok, I get it, it really is a pain in the ass.. // But it's the only way to have maintainable code diff --git a/src/it/reyboz/bustorino/middleware/StopsDB.java b/src/it/reyboz/bustorino/middleware/StopsDB.java --- a/src/it/reyboz/bustorino/middleware/StopsDB.java +++ b/src/it/reyboz/bustorino/middleware/StopsDB.java @@ -42,10 +42,10 @@ private static String QUERY_WHERE_ID = "ID = ?"; private static String QUERY_WHERE_LAT_AND_LNG_IN_RANGE = "lat >= ? AND lat <= ? AND lon >= ? AND lon <= ?"; private static String[] QUERY_COLUMN_name = {"name"}; - private static String[] QUERY_COLUMN_location = {"location"}; - private static String[] QUERY_COLUMN_route = {"route"}; - private static String[] QUERY_COLUMN_everything = {"name", "location", "type", "lat", "lon"}; - private static String[] QUERY_COLUMN_everything_and_ID = {"ID", "name", "location", "type", "lat", "lon"}; + private static final String[] QUERY_COLUMN_location = {"location"}; + private static final String[] QUERY_COLUMN_route = {"route"}; + private static final String[] QUERY_COLUMN_everything = {"name", "location", "type", "lat", "lon"}; + private static final String[] QUERY_COLUMN_everything_and_ID = {"ID", "name", "location", "type", "lat", "lon"}; private static String DB_NAME = "stops.sqlite"; private static int DB_VERSION = 1; @@ -273,7 +273,9 @@ locationWhichSometimesIsAnEmptyString = null; } - stops[i++] = new Stop(stopID, result.getString(colName), null, locationWhichSometimesIsAnEmptyString, type, getRoutesByStop(stopID), result.getDouble(colLat), result.getDouble(colLon)); + stops[i++] = new Stop(stopID, result.getString(colName), null, + locationWhichSometimesIsAnEmptyString, type, getRoutesByStop(stopID), + result.getDouble(colLat), result.getDouble(colLon)); } } catch(SQLiteException e) {