package esl.cuenet.generative.structs; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import esl.system.SysLoggerUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; import org.apache.log4j.Logger; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Random; public class SpaceTimeValueGenerators { static { SysLoggerUtils.initLogger(); } Random randomGenerator = new Random(); Logger logger = Logger.getLogger(getClass()); private ArrayList<String> locationKeyList = Lists.newArrayList(); private HashMap<String, LatLonPair> locationsMap = Maps.newHashMap(); private final double maxDist; public SpaceTimeValueGenerators(Iterator<String> iter) { String bounds = null; if (iter.hasNext()) bounds = iter.next(); else throw new RuntimeException(); double minLat = 1000, minLon = 1000; double maxLat = -1000, maxLon = -1000; String tmp; while (iter.hasNext()) { tmp = iter.next(); String[] parts = tmp.split(","); locationKeyList.add(parts[0]); LatLonPair p = new LatLonPair(parts[1], parts[2]); locationsMap.put(parts[0], p); if (p.latitude < minLat) minLat = p.latitude; if (p.latitude > maxLat) maxLat = p.latitude; if (p.longitude < minLon) minLon = p.longitude; if (p.longitude > maxLon) maxLon = p.longitude; } logger.info("bounds = " + minLat + ", " + minLon + " -> " + maxLat + ", " + maxLon); LatLonPair p1 = new LatLonPair(minLat, minLon); LatLonPair p2 = new LatLonPair(maxLat, maxLon); maxDist = p1.distance(p2); } public SpaceTimeValueGenerators(String locationValuesFilename) throws IOException { LineIterator iter = FileUtils.lineIterator(new File(locationValuesFilename)); String bounds = null; if (iter.hasNext()) bounds = iter.next(); else throw new RuntimeException(); double minLat = 1000, minLon = 1000; double maxLat = -1000, maxLon = -1000; String tmp; while (iter.hasNext()) { tmp = iter.next(); String[] parts = tmp.split(","); locationKeyList.add(parts[0]); LatLonPair p = new LatLonPair(parts[1], parts[2]); locationsMap.put(parts[0], p); if (p.latitude < minLat) minLat = p.latitude; if (p.latitude > maxLat) maxLat = p.latitude; if (p.longitude < minLon) minLon = p.longitude; if (p.longitude > maxLon) maxLon = p.longitude; } logger.info("bounds = " + minLat + ", " + minLon + " -> " + maxLat + ", " + maxLon); LatLonPair p1 = new LatLonPair(minLat, minLon); LatLonPair p2 = new LatLonPair(maxLat, maxLon); maxDist = p1.distance(p2); iter.close(); } public Iterator<String> getLocationValueIterator() { return locationKeyList.iterator(); } public double getLatitude (String key) { return locationsMap.get(key).latitude; } public double getLongitude (String key) { return locationsMap.get(key).longitude; } public double distance (String key1, String key2) { if (key1 == null || key2 == null) return 0; return locationsMap.get(key1).distance(locationsMap.get(key2)); } public double getMaxDist() { return maxDist; } public static class LatLonPair { public double latitude; public double longitude; public LatLonPair (double latitude, double longitude) { this.latitude = latitude; this.longitude = longitude; } public LatLonPair (String latitude, String longitude) { this.latitude = Double.parseDouble(latitude); this.longitude = Double.parseDouble(longitude); } public double distance (LatLonPair other) { double radiusOfEarthInKms = 6378.137; double distance = Math.acos( Math.sin(DtoR(this.latitude)) * Math.sin(DtoR(other.latitude)) + Math.cos(DtoR(this.latitude)) * Math.cos(DtoR(other.latitude)) * Math.cos(DtoR(other.longitude)-DtoR(this.longitude))); return (distance * radiusOfEarthInKms); } private double DtoR(double d) { return d*0.0174532925; } } public long getUniformTimestamp(long startRange, long endRange) { double d = randomGenerator.nextDouble(); return (long) (startRange + ((endRange - startRange) * d)); } public long getGaussianTimestamp(long mean, long variance) { return (long) (mean + randomGenerator.nextGaussian() * variance); } }