--- android/TrainInfo/src/dk/thoerup/traininfo/provider/OfflineStationProvider.java 2011/07/07 19:07:55 1547 +++ android/TrainInfo/src/dk/thoerup/traininfo/provider/OfflineStationProvider.java 2011/07/09 07:26:15 1568 @@ -4,11 +4,13 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.ArrayList; +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; @@ -19,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; @@ -28,6 +31,8 @@ public boolean loadStations(Context context) throws Exception { + long start = System.currentTimeMillis(); + stations.entries.clear(); //TODO: remove File parent = context.getFilesDir(); @@ -36,8 +41,8 @@ if (!stationsFile.exists()) return false; - int size = (int) stationsFile.length(); - /*byte data[] = new byte[size]; + /*int size = (int) stationsFile.length(); + byte data[] = new byte[size]; RandomAccessFile raf = new RandomAccessFile(stationsFile, "r"); raf.readFully(data); @@ -46,21 +51,30 @@ stations = serializer.read(StationBean.class, new String(data, "ISO-8859-1") );*/ - try { - ObjectInputStream in = new ObjectInputStream( new FileInputStream(stationsFile) ); - Object o; - while ( (o=in.readObject()) != null ) { - stations.entries.add( (StationEntry) o); - } - in.close(); - } catch (EOFException e) { - //do nothing; + + ObjectInputStream in = new ObjectInputStream( new FileInputStream(stationsFile) ); + + int length = in.readInt(); // first field is the length + + for (int i=0; i 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); @@ -155,9 +195,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(); + } + }