@Override public List<STPoint> getSequence(STPoint start, STPoint end) { STPoint boundValues = new STPoint(Constants.PoK.X_RADIUS, Constants.PoK.Y_RADIUS, Constants.PoK.T_RADIUS); STPoint startNN = this.nearestNeighbor(start, boundValues, 1).get(0); STPoint endNN = this.nearestNeighbor(end, boundValues, 1).get(0); float minT = startNN.getT() > endNN.getT() ? startNN.getT() : endNN.getT(); float maxT = startNN.getT() > endNN.getT() ? startNN.getT() : endNN.getT(); // // String query = "SELECT id,minX,maxX,minY,maxY,minT,maxT from " + // this.table_identifier; // query += "WHERE minT<=" + maxT + " AND minT>=" + minT; // query += "ORDER BY minT ASC"; // // SQLiteDatabase db = this.getReadableDatabase(); STPoint minPoint = new STPoint(); STPoint maxPoint = new STPoint(); minPoint.setT(minT); maxPoint.setT(maxT); return this.range(new STRegion(minPoint, maxPoint)); }
@Override public STRegion getBoundingBox() { // TODO: get bounding box through R-Tree shadow tables SQLiteDatabase db = this.getReadableDatabase(); String query = "SELECT minX FROM " + this.table_identifier + " ORDER BY minX ASC LIMIT 1;"; float minX = getRowValueHelper(db, query, 0); query = "SELECT minY FROM " + this.table_identifier + " ORDER BY minY ASC Limit 1;"; float minY = getRowValueHelper(db, query, 0); query = "SELECT minT FROM " + this.table_identifier + " ORDER BY minT ASC Limit 1;"; float minT = getRowValueHelper(db, query, 0); query = "SELECT maxX FROM " + this.table_identifier + " ORDER BY maxX DESC Limit 1;"; float maxX = getRowValueHelper(db, query, 0); query = "SELECT maxY FROM " + this.table_identifier + " ORDER BY maxY DESC Limit 1;"; float maxY = getRowValueHelper(db, query, 0); query = "SELECT maxT FROM " + this.table_identifier + " ORDER BY maxT DESC Limit 1;"; float maxT = getRowValueHelper(db, query, 0); STPoint mins = new STPoint(minX, minY, minT); STPoint maxs = new STPoint(maxX, maxY, maxT); if (Constants.SPATIAL_TYPE == Constants.SpatialType.GPS) { STPoint.add(mins, Constants.NEG_FLOAT_BUDGE); STPoint.add(maxs, Constants.POS_FLOAT_BUDGE); } return new STRegion(mins, maxs); }
@Override public void insert(STPoint point) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("minX", point.getX()); values.put("maxX", point.getX()); values.put("minY", point.getY()); values.put("maxY", point.getY()); values.put("minT", point.getT()); values.put("maxT", point.getT()); db.insert( this.table_identifier, // table null, // nullColumnHack values); // key/value -> keys = column names/ values = column values db.close(); }
@Override public List<STPoint> nearestNeighbor(STPoint needle, STPoint boundValues, int n) { // TODO support more than one nearest neighbor if (n != 1) { throw new RuntimeException("Nearest Neighbor does not support N != 1"); } List<STPoint> candPoints = new ArrayList<STPoint>(); for (int i = 0; i < 20; i++) { try { STRegion miniRegion = GPSLib.getSpaceBoundQuick(needle, boundValues, SPATIAL_TYPE); candPoints = range(miniRegion); if (candPoints.size() >= n) { break; } int step = (int) Math.pow(i, 3); boundValues.setX(step * boundValues.getX()); boundValues.setY(step * boundValues.getY()); boundValues.setT(step * boundValues.getT()); } catch (LSTFilterException e) { e.printStackTrace(); } } STPoint minPoint = null; double minVal = Double.MAX_VALUE; for (STPoint point : candPoints) { // ToDo: optimize this since we use the same needle each time, some values should drop out of // dist calc. // ToDO: optimize by using squared values of distance instead of ones using sqrt (expensive) try { double distance = GPSLib.distanceBetween(needle, point, SPATIAL_TYPE); if (distance < minVal) { minVal = distance; minPoint = point; } } catch (LSTFilterException e) { e.printStackTrace(); } } List<STPoint> minPoints = new ArrayList<STPoint>(); minPoints.add(minPoint); return minPoints; }
@Override public List<STPoint> range(STRegion range) { SQLiteDatabase db = this.getReadableDatabase(); String query = "SELECT id,minX,maxX,minY,maxY,minT,maxT from " + this.table_identifier + " "; STPoint mins = range.getMins(); STPoint maxs = range.getMaxs(); String prefix = " WHERE "; if (mins.hasX() && maxs.hasX()) { query += prefix + " minX >= " + String.valueOf(mins.getX()) + " AND maxX <= " + String.valueOf(maxs.getX()); prefix = " AND "; } if (mins.hasY() && maxs.hasY()) { query += prefix + " minY >= " + String.valueOf(mins.getY()) + " AND maxY <= " + String.valueOf(maxs.getY()); prefix = " AND "; } if (mins.hasT() && maxs.hasT()) { query += prefix + " minT >= " + String.valueOf(mins.getT()) + " AND maxT <= " + String.valueOf(maxs.getT()); prefix = " AND "; } Cursor cur = db.rawQuery(query, null); List<STPoint> points = cursorToList(cur); db.close(); return points; }