package dk.daoas.fulddaekning; import geocode.GeoPoint; import geocode.kdtree.KDTree; import java.io.File; import java.io.FileReader; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; public class LookupMain { static class LookupResult { double bedsteAfstand = 9999999.999; Adresse bedsteAdr = null; } static final String CONFIG_FILENAME = "fulddaekning.properties"; static boolean rename_tables; static SafeProperties conf; static int max_workers; static boolean verbose; static String distributor; final static Logger logger = Logger.getLogger( LookupMain.class.toString() ); public static void main(String[] args) throws Exception { //Setup j.u.l Logger Logger root = Logger.getLogger(""); FileHandler fhandler = new FileHandler("fulddaekning.log"); // Ingen max størrelse, ingen rotation og ingen append fhandler.setFormatter( new SimpleFormatter() ); root.addHandler( fhandler ); File confFile = new File( CONFIG_FILENAME ); if (! confFile.exists() ) { logger.warning("Config file not found: " + CONFIG_FILENAME); System.exit(1); } conf = new SafeProperties(); conf.load( new FileReader(confFile) ); verbose = Boolean.parseBoolean( conf.getSafeProperty("VERBOSE") ); logger.info("Starting with VERBOSE:" + verbose); rename_tables = Boolean.parseBoolean( conf.getSafeProperty("RENAMETABLES") ); logger.info("Starting with RENAMETABLES:" + rename_tables); distributor = conf.getSafeProperty("DISTRIBUTOR"); distributor = distributor.toUpperCase(); logger.info("Starting for DISTRIBUTOR:" + distributor); Constants.init(distributor); 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 start = System.currentTimeMillis(); int antalDaekkedeAdresser = -1; if (testRun == false) { logger.info("Finder postnumre"); Set postnumre = db.hentPostnumreCache(); // Først validerer vi BBox på alle postnummre, for at undgå fuldt stop midt i beregningen for(short postnr : postnumre) { // logger.info("Validerer BBox for " + postnr); BoundingBox bbox = db.getBoundingbox(postnr); bbox.validateBbox(); } 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() ); KDTree addressTree = new KDTree( geopoints ); hoTrees.put(ho, addressTree); } db.resetResultTable(); 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(); result.bedsteAdr = (Adresse) addressTree.findNearest(qAdresse); result.bedsteAfstand = GeoPointHelper.beregnAfstand(qAdresse, result.bedsteAdr); 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 { logger.info( "Rename tables is disabled !!!" ); } } else { /// Test /* db.resetResultTable(); 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 ; logger.info("Fuld load done : " + formatMilliSeconds(elapsed) ); 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 + "%" ); } static String formatMilliSeconds(long milliseconds) { int mseconds = (int) milliseconds % 1000; int seconds = (int) (milliseconds / 1000) % 60 ; int minutes = (int) ((milliseconds / (1000*60)) % 60); int hours = (int) ((milliseconds / (1000*60*60)) % 24); return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, mseconds); } }