--- dao/FuldDaekningWorker/src/dk/daoas/fulddaekning/LookupMain.java 2014/12/10 10:06:32 2244 +++ dao/FuldDaekningWorker/src/dk/daoas/fulddaekning/LookupMain.java 2015/09/27 18:20:41 2708 @@ -2,12 +2,28 @@ import java.io.File; import java.io.FileReader; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; import java.util.logging.FileHandler; +import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; +import com.jwetherell.algorithms.data_structures.KdTree; + +import dk.daoas.fulddaekning.osrm.OSRMHelper; + public class LookupMain { + + static class LookupResult { + double bedsteAfstand = 9999999.999; + Adresse bedsteAdr = null; + } static final String CONFIG_FILENAME = "fulddaekning.properties"; @@ -23,12 +39,11 @@ final static Logger logger = Logger.getLogger( LookupMain.class.toString() ); - static Statistik flestDaekkede = new Statistik(); - static Statistik flestIkkeDaekkede = new Statistik(); - static Statistik mestBrugteTid = new Statistik(); - static Statistik stoersteDataset = new Statistik(); - static Adresse[] alleDaekkedeAdresser; + static final int MAX_RESULTS = 100; + + static OSRMHelper osrmHelper = new OSRMHelper(); + public static void main(String[] args) throws Exception { @@ -51,16 +66,6 @@ conf = new SafeProperties(); conf.load( new FileReader(confFile) ); - max_workers = Integer.parseInt( conf.getSafeProperty("MAX_WORKERS") ); - if (max_workers <= 0) { - logger.info("!!! AUTO-DETECT MAX_WORKERS !!!"); - int cores = Runtime.getRuntime().availableProcessors(); - cores -= 1;//Efterlad 1 core/cpu i reserve til systemet - - max_workers = Math.max(1, cores); //Dog skal der som minimum være 1 core til beregning - - } - logger.info("Starting with MAX_WORKERS:" + max_workers); verbose = Boolean.parseBoolean( conf.getSafeProperty("VERBOSE") ); @@ -77,42 +82,103 @@ Constants consts = Constants.getInstance(); Database db = new Database(conf); - - - + Adresse ikkeDaekkede[] = db.hentAlleIkkedaekkedeAdresser(consts.getMinPostnr(), consts.getMaxPostnr() ); + logger.info("Antal ikke-daekkede: " + ikkeDaekkede.length); boolean testRun= false; + int antalFundne = 0; + long beregnStart =0; long start = System.currentTimeMillis(); + int antalDaekkedeAdresser = -1; if (testRun == false) { logger.info("Finder postnumre"); - List postnumre = db.hentPostnumre(); + Set postnumre = db.hentPostnumreCache(); // Først validerer vi BBox på alle postnummre, for at undgå fuldt stop midt i beregningen - for(String postnr : postnumre) { // + for(short postnr : postnumre) { // logger.info("Validerer BBox for " + postnr); BoundingBox bbox = db.getBoundingbox(postnr); bbox.validateBbox(); } - if (consts.doExtendedLookup()) { - logger.info("Henter alle daekkede adresser"); - alleDaekkedeAdresser = db.hentAlleDaekkedeAdresser(); - logger.info( "AlleDaekkedeAdresser.length=" + alleDaekkedeAdresser.length); - } + + logger.info("Henter alle daekkede adresser"); + antalDaekkedeAdresser = db.hentAlleDaekkedeAdresser(); + logger.info( "AlleDaekkedeAdresser.length=" + antalDaekkedeAdresser ); + Map> addrHoList = db.getDaekkedeAdresserHO(); + + Map> hoTrees = new HashMap>(); + + for ( Map.Entry> entry : addrHoList.entrySet() ) { + short ho = entry.getKey(); + List geopoints = entry.getValue(); + + logger.info("Opbygger KDTree for " + ho + " - antal=" + geopoints.size() ); + + @SuppressWarnings("unchecked") + List tmpPoints = (List)(List) geopoints; + + KdTree addressTree = new KdTree( tmpPoints ); + hoTrees.put(ho, addressTree); + } - //pre-check er ok - reset tmp tabel og start søgningen db.resetResultTable(); + + beregnStart = System.currentTimeMillis(); + logger.info("Starter beregning"); + + final int workerId = -1; + //pre-check er ok - reset tmp tabel og start søgningen + + for (Adresse qAdresse : ikkeDaekkede) { + + short ho = qAdresse.ho; + KdTree addressTree = hoTrees.get(ho); + + LookupResult result = new LookupResult(); + Collection res = addressTree.nearestNeighbourSearch(MAX_RESULTS, qAdresse); + if (res.size() > MAX_RESULTS ) { + System.out.println("Returnerede mere end MAX_RESULTS> " + res.size() ); + System.exit(0); + } + + + result.bedsteAdr = osrmHelper.getNearestViaTable(qAdresse, res); + System.out.println("Bedste:" + result.bedsteAdr ); + + result.bedsteAfstand = GeoPointHelper.beregnAfstand(qAdresse, result.bedsteAdr); + - for(String postnr : postnumre) { - Lookup lookup = new Lookup(postnr, db); - lookup.doLookup(); + if (result.bedsteAfstand <= consts.getMaxDistance() ) { //Gem kun hvis distancen er under max_distance for distributøren + if (verbose == true) { + logger.fine("(" +workerId + ") Bedste: " + qAdresse + "==>" + result.bedsteAdr + " ::: " + result.bedsteAfstand ); + } + + antalFundne++; + + try { + db.gemResultat(qAdresse, result.bedsteAdr, result.bedsteAfstand); + } catch (SQLException e) { + logger.log(Level.WARNING, "Error saving result", e); + logger.warning("Shutting down"); + + System.exit(0); //hvis at indsættelsen fejler skal vi afbryde med det samme + } + } else { + if (verbose == true) { + System.out.println("For stor afstand: " + qAdresse + " > " + result.bedsteAfstand); + } + } + } + db.saveBatch(); + if (rename_tables) { db.renameResultTables(); } else { @@ -123,44 +189,35 @@ } else { /// Test + /* db.resetResultTable(); - if (consts.doExtendedLookup()) { - alleDaekkedeAdresser = db.hentAlleDaekkedeAdresser(); - logger.info( "AlleDaekkedeAdresser.length=" + alleDaekkedeAdresser.length); - } - - Lookup lookup = new Lookup("458x", db); - lookup.doLookup(); + + alleDaekkedeAdresser = db.hentAlleDaekkedeAdresser(); + logger.info( "AlleDaekkedeAdresser.length=" + alleDaekkedeAdresser.size()); + + short post = (short) 2700; + Lookup lookup = new Lookup(post, db, threadPool); + lookup.doLookup();*/ } + long now = System.currentTimeMillis(); long elapsed = now - start ; + long elapsedBeregn = now - beregnStart; - logger.info("Mest brugte tid: " + mestBrugteTid); - logger.info("Flest Ikke-dækkede, " + flestIkkeDaekkede); - logger.info("Flest Dækkede, " + flestDaekkede); - logger.info("Største Dataset, " + stoersteDataset); + logger.info("Fuld load done : " + formatMilliSeconds(elapsed) ); + logger.info("Fuld load done (beregning) : " + formatMilliSeconds(elapsedBeregn) ); + logger.info("Antal daekkede : " + antalDaekkedeAdresser ); + logger.info("Antal ikke-daekkede : " + ikkeDaekkede.length ); + logger.info("Heraf, antal fundne : " + antalFundne ); + + logger.info( String.format("Fandt adresser til : %.2f %%", (antalFundne*100.0)/ikkeDaekkede.length ) ); + //logger.info("Fandt adresser til : " + (antalFundne*100.0)/ikkeDaekkede.length + "%" ); } - public static void saveStatistics(Statistik stat) { - if (stat.antalDaekkede > flestDaekkede.antalDaekkede) { - flestDaekkede = stat; - } - if (stat.antalIkkeDaekkede > flestIkkeDaekkede.antalIkkeDaekkede) { - flestIkkeDaekkede = stat; - } - - if (stat.totalDataset > mestBrugteTid.totalDataset) { - stoersteDataset = stat; - } - - if (stat.forbrugtTid > mestBrugteTid.forbrugtTid) { - mestBrugteTid = stat; - } - } static String formatMilliSeconds(long milliseconds) { int mseconds = (int) milliseconds % 1000; @@ -169,5 +226,6 @@ int hours = (int) ((milliseconds / (1000*60*60)) % 24); return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, mseconds); - } + } + }