--- android/TrainInfo/src/dk/thoerup/traininfo/provider/OfflineStationProvider.java 2011/07/06 20:59:19 1545 +++ android/TrainInfo/src/dk/thoerup/traininfo/provider/OfflineStationProvider.java 2011/07/08 13:58:21 1559 @@ -1,11 +1,16 @@ package dk.thoerup.traininfo.provider; +import java.io.EOFException; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.ArrayList; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.URLEncoder; import java.util.Collections; import java.util.Comparator; +import java.util.LinkedList; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; @@ -16,6 +21,7 @@ import dk.thoerup.android.traininfo.common.StationBean; import dk.thoerup.android.traininfo.common.StationEntry; import dk.thoerup.genericjavautils.HttpUtil; +import dk.thoerup.traininfo.util.DownloadUtil; import dk.thoerup.traininfo.util.IntSet; import dk.thoerup.traininfo.util.XmlUtil; @@ -25,37 +31,65 @@ public boolean loadStations(Context context) throws Exception { + long start = System.currentTimeMillis(); + + stations.entries.clear(); //TODO: remove + File parent = context.getFilesDir(); - File stationsFile = new File(parent, "stations.xml"); + File stationsFile = new File(parent, "stations.bin"); if (!stationsFile.exists()) return false; - int size = (int) stationsFile.length(); + /*int size = (int) stationsFile.length(); byte data[] = new byte[size]; RandomAccessFile raf = new RandomAccessFile(stationsFile, "r"); raf.readFully(data); Serializer serializer = new Persister(); - stations = serializer.read(StationBean.class, new String(data, "ISO-8859-1") ); + stations = serializer.read(StationBean.class, new String(data, "ISO-8859-1") );*/ + + + try { + ObjectInputStream in = new ObjectInputStream( new FileInputStream(stationsFile) ); + Object o; + StationEntry e = null; + while ( (o=in.readObject()) != null ) { + e = (StationEntry) o; + e.updateSearch(); + stations.entries.add( e ); + } + in.close(); + } catch (EOFException e) { + //do nothing; + } Log.e("OFFLINE", "loaded" + stations.entries.size()); + logElapsedTime(start, "loadStations"); return true; } - public void downloadStations(Context context) throws IOException { + public void downloadStations(Context context) throws Exception { File parent = context.getFilesDir(); - File stationsFile = new File(parent, "stations.xml"); + File stationsFile = new File(parent, "stations.bin"); + byte data[] = HttpUtil.getContent(XmlUtil.SERVICE_BASE + "/LocateStations?dump=1", 5000); + Serializer serializer = new Persister(); + stations = serializer.read(StationBean.class, new String(data, "ISO-8859-1") ); + - RandomAccessFile raf = new RandomAccessFile(stationsFile, "rw"); + ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(stationsFile) ); Log.e("OFFLINE", "data size" + data.length); - raf.setLength(0); //truncate - raf.write(data); - raf.close(); + + for (StationEntry entry : stations.entries) { + entry.updateSearch(); //prepare name fields for byName search + out.writeObject(entry); + } + + out.close(); } @@ -64,63 +98,86 @@ public void purgeOldEntries() { } + Comparator distanceComparator = new Comparator() { + @Override + public int compare(StationEntry object1, StationEntry object2) { + if (object1.getCalcdist() == object2.getCalcdist()) + return 0; + + if (object1.getCalcdist() > object2.getCalcdist()) + return 1; + else + return -1; + } + }; @Override public StationBean lookupStationsByLocation(Location location) { + statsByLocation(location); + + long start = System.currentTimeMillis(); Location tmpLoc = new Location("GPS"); - ArrayList entries = new ArrayList() ; + LinkedList entries = new LinkedList() ; for (StationEntry entry : stations.entries) { tmpLoc.setLatitude(entry.getLatitude()); tmpLoc.setLongitude(entry.getLongitude()); - entry.setCalcdist( (int) location.distanceTo(tmpLoc) ); - entries.add(entry); + int distance = (int) location.distanceTo(tmpLoc); - } - - Collections.sort( entries, new Comparator() { - @Override - public int compare(StationEntry object1, StationEntry object2) { - if (object1.getCalcdist() == object2.getCalcdist()) - return 0; + if (entries.size() <8 || entries.getLast().getCalcdist() > distance) { + entry.setCalcdist(distance); - if (object1.getCalcdist() > object2.getCalcdist()) - return 1; - else - return -1; - } - - }); + if (entries.size() == 8) + entries.removeLast(); + + entries.addLast(entry); + + Collections.sort( entries, distanceComparator); + } + } + logElapsedTime(start, "location_stage1"); + Collections.sort( entries, distanceComparator); StationBean tmpStations = new StationBean(); for (int i = 0; i<8; i++) { tmpStations.entries.add( entries.get(i) ); } + logElapsedTime(start, "location"); return tmpStations; } + + private void logElapsedTime(long start, String method) { + long now = System.currentTimeMillis(); + + Log.i("TrainInfo", "Search by " + method + " elapsed " + (now-start) ); + } @Override public StationBean lookupStationsByName(String name) { + long start = System.currentTimeMillis(); + name = name.toLowerCase(); StationBean tmpStations = new StationBean(); for (StationEntry entry : stations.entries) { - if (entry.getName().toLowerCase().startsWith(name) ) { + if (entry.nameLower.startsWith(name) || entry.nameInternational.startsWith(name) ) { tmpStations.entries.add(entry); } } - + logElapsedTime(start, "name"); return tmpStations; } @Override public StationBean lookupStationsByIds(String ids) { + statsByIds(ids); + IntSet idset = new IntSet(); idset.fromString(ids); @@ -131,9 +188,52 @@ } } + return tmpStations; + } + + + private void statsByLocation(Location location) { + double lat = XmlStationProvider.roundToPlaces(location.getLatitude(), 4); + double lng = XmlStationProvider.roundToPlaces(location.getLongitude(), 4); + + final String url = XmlUtil.SERVICE_BASE + "/LocateStations?latitude=" + lat + "&longitude=" + lng + "&dummy=1"; + Log.i("url", url); + urlSender(url); + } + + private void statsByName(String name) { + try { + name = URLEncoder.encode(name, "ISO8859-1"); + } catch (Exception e) { + Log.e("lookupStations", "Encoding failed", e);//if encoding fails use original and hope for the best + } - return tmpStations; + String url = XmlUtil.SERVICE_BASE + "/LocateStations?name=" + name + "&dummy=1"; + Log.i("url", url); + urlSender(url); } + + private void statsByIds(String ids) { + final String url = XmlUtil.SERVICE_BASE + "/LocateStations?list=" + ids + "&dummy=1"; + Log.i("url", url); + urlSender(url); + } + + private void urlSender(final String url) { + Thread t = new Thread(new Runnable() { + + @Override + public void run() { + try { + DownloadUtil.getContentString(url, 15000, "ISO-8859-1"); + } catch (IOException e) { + Log.e("TrainInfo", "stats failed"); + } + } + }); + t.start(); + } + }