--- dao/DaoAdresseService/src/dk/daoas/daoadresseservice/AdressSearch.java 2015/02/12 13:57:32 2267 +++ dao/DaoAdresseService/src/dk/daoas/daoadresseservice/AdressSearch.java 2015/02/16 13:49:56 2310 @@ -1,21 +1,426 @@ package dk.daoas.daoadresseservice; +import java.sql.SQLException; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import dk.daoas.daoadresseservice.AddressUtils.SplitResult; +import dk.daoas.daoadresseservice.beans.Address; +import dk.daoas.daoadresseservice.beans.ExtendedBean; +import dk.daoas.daoadresseservice.beans.HundredePctBean; +import dk.daoas.daoadresseservice.beans.SearchResult; +import dk.daoas.daoadresseservice.beans.SearchResult.Status; +import dk.daoas.daoadresseservice.db.DatabaseLayer; public class AdressSearch { - HashMap> searchPostnrVejnavnDavid = new HashMap>(); + Map> searchPostnrVejnavnGadeid; + Map> searchGadeidentAdresser; + + List
alleAdresser; + + Map helperCache; + + + Map hundredePct; - public void search(int postnr, String adresse) throws SearchException { - HashMap postnrVeje = searchPostnrVejnavnDavid.get(postnr); + public SearchResult search(String postnrStr, String adresse) { + + int postnr=0; + boolean google = false; + boolean osm = false; + String helperSearchKey = ""; + + try { + postnr = Integer.parseInt(postnrStr); + } catch (Exception E) { + return new SearchResult(Status.ERROR_UNKNOWN_POSTAL); + } + + Map postnrVeje = searchPostnrVejnavnGadeid.get(postnr); if (postnrVeje == null) { - throw new SearchException("Ukendt postnr"); + return new SearchResult(Status.ERROR_UNKNOWN_POSTAL); + } + + + SplitResult split = AddressUtils.splitAdresse(adresse); + String vasketVejnavn = AddressUtils.vaskVejnavn( split.vej ); + + if (split.husnr.length() == 0) { + return new SearchResult(Status.ERROR_MISSING_HOUSENUMBER); + } + + Long gadeident = postnrVeje.get(vasketVejnavn); + + + if ( gadeident == null) { + helperSearchKey = "" + postnr + "/" + vasketVejnavn; + gadeident = helperCache.get(helperSearchKey); + } + + + if ( gadeident == null) { + String googleVej = GeocodeHelper.googleHelper(postnr, split.vej ); + google = true; + + if (googleVej != null) { + String googleVasket = AddressUtils.vaskVejnavn( googleVej ); + gadeident = postnrVeje.get(googleVasket); + + if (gadeident != null) { + helperCache.put(helperSearchKey, gadeident); + } + } + } + + if ( gadeident == null) { + String osmVej = GeocodeHelper.openstreetmapHelper(postnr, split.vej ); + osm = true; + + if (osmVej != null) { + String osmVasket = AddressUtils.vaskVejnavn( osmVej ); + gadeident = postnrVeje.get(osmVasket); + + if (gadeident != null) { + helperCache.put(helperSearchKey, gadeident); + } + } + } + + if (gadeident == null) { + return new SearchResult(Status.ERROR_UNKNOWN_STREETNAME); + } + + Map gade = searchGadeidentAdresser.get(gadeident); //Denne søgning må ikke fejle + + + String husnrSearch = "" + split.husnr + split.litra; + Address addr = gade.get(husnrSearch); + + if (addr == null) { + return new SearchResult(Status.ERROR_UNKNOWN_ADDRESSPOINT); } + if (addr.daekningsType == DaekningsType.DAEKNING_IKKEDAEKKET) { + return new SearchResult(Status.STATUS_NOT_COVERED); + } + if (addr.distributor.equals("LUKKET")) { + return new SearchResult(Status.STATUS_NOT_COVERED); //Skal vi have en special status til Lukkede adresser ? + } + SearchResult res = new SearchResult(addr); + res.google = google; + res.osm = osm; + return res; } + + public void buildSearchStructures() throws SQLException{ + searchPostnrVejnavnGadeid = new HashMap>(); + searchGadeidentAdresser = new HashMap>(); + helperCache = new ConcurrentHashMap(); + + long start1 = System.currentTimeMillis(); + System.out.println("Build -- stage 1"); + + alleAdresser = DatabaseLayer.getAllAdresses(); + + + /* Mapper mellem db Row ID og adresse noden */ + Map idAddressMap = new HashMap( alleAdresser.size() ); + + for (Address a : alleAdresser) { + idAddressMap.put(a.id, a); + + Map postnrVeje = searchPostnrVejnavnGadeid.get(a.postnr); + + if (postnrVeje == null) { + postnrVeje = new ConcurrentHashMap(); + searchPostnrVejnavnGadeid.put(a.postnr, postnrVeje); + } + + String vasketVejnavn = AddressUtils.vaskVejnavn(a.vejnavn); + Long gadeident = postnrVeje.get(vasketVejnavn); + if (gadeident == null) { + //postnrVeje.put(vasketVejnavn, a.gadeid); + + Set aliaser = findVejAliaser(a.vejnavn); + for(String alias : aliaser) { + String vasketAlias = AddressUtils.vaskVejnavn(alias); + postnrVeje.put(vasketAlias, a.gadeid); + } + + } + + Map gade = searchGadeidentAdresser.get(a.gadeid); + if (gade == null) { + gade = new HashMap(); + searchGadeidentAdresser.put(a.gadeid, gade); + } + String husnrSearch = "" + a.husnr + a.husnrbogstav; + gade.put(husnrSearch, a); + } + + + //////////////////////////////////////////////////////////////////////////////////////// + long start2 = System.currentTimeMillis(); + System.out.println("Build, stage1 elapsed: " + (start2-start1) ); + System.out.println("Build -- stage 2 udvidet dækning"); + + List extDao = DatabaseLayer.getExtendedAdresslist(); + for (ExtendedBean eb : extDao) { + + Address orgAddress = idAddressMap.get(eb.orgId); + if (orgAddress == null) + continue; + + Address targetAddress = idAddressMap.get(eb.targetId); + if (targetAddress == null) + continue; + + if (orgAddress.distributor != null && orgAddress.distributor.equals("LUKKET")) { + continue; + } + + if (targetAddress.distributor.equals("LUKKET")) { + continue; + } + + orgAddress.extTarget = targetAddress; + orgAddress.extAfstand = eb.afstand; + + boolean covered = false; + if (targetAddress.distributor.equals("DAO")) { + orgAddress.rute = calculateExtendedDaoRoute(eb,orgAddress,targetAddress); + if (orgAddress.rute != null) { + orgAddress.koreliste = targetAddress.koreliste; + covered = true; + } + } + + if (targetAddress.distributor.equals("BK")) { + orgAddress.koreliste = calculateExtendedBkKoreliste(eb,orgAddress,targetAddress); + if (orgAddress.koreliste != null) { + orgAddress.rute = targetAddress.rute; + covered = true; + } + } + + if (covered) { //Kopier resten af felterne + orgAddress.daekningsType = DaekningsType.DAEKNING_UDVIDET; + orgAddress.dbkBane = targetAddress.dbkBane; + + /* Sådan gør den gamle service */ + orgAddress.kommunekode = targetAddress.kommunekode; + orgAddress.vejkode = targetAddress.vejkode; + + orgAddress.distributor = targetAddress.distributor; + } + } + + // nu skal vi ikke bruge idAddressMap længere + idAddressMap = null; + + ////////////////////////////////////////////////////////////////////////////////////// + long start3 = System.currentTimeMillis(); + System.out.println("Build, stage2 elapsed: " + (start3-start2) ); + System.out.println("Build -- stage 3 - 100pct"); + + hundredePct = DatabaseLayer.get100PctList(); + for (Address addr : alleAdresser) { + if (addr.daekningsType != DaekningsType.DAEKNING_IKKEDAEKKET) { + continue; + } + + if (addr.distributor != null && addr.distributor.equals("LUKKET")) { + continue; + } + + + HundredePctBean bean = hundredePct.get(addr.postnr); + if (bean == null) { + continue; + } + + addr.daekningsType = DaekningsType.DAEKNING_100PCT; + addr.rute = bean.rute; + addr.koreliste = bean.koreliste; + addr.dbkBane = bean.dbkBane; + addr.distributor = bean.distributor; + } + + //////////////////////////////////////////////////////////////////////////////////// + long stop = System.currentTimeMillis(); + System.out.println("Build, stage3 elapsed: " + (stop-start3) ); + System.out.println("Build -- Gathering statistics"); + + int direkteCount = 0; + int extendedCount = 0; + int hundredePctCount = 0; + int ikkeDaekketCount = 0; + + for (Address addr : alleAdresser) { + switch (addr.daekningsType) { + case DAEKNING_DIREKTE: + direkteCount++; + break; + case DAEKNING_UDVIDET: + extendedCount++; + break; + case DAEKNING_100PCT: + hundredePctCount++; + break; + default: + ikkeDaekketCount++; + } + } + + System.out.println("Build: direkteCount: " + direkteCount); + System.out.println("Build: extendedCount: " + extendedCount); + System.out.println("Build: hundredePctCount: " + hundredePctCount); + System.out.println("Build: ikkeDaekketCount: " + ikkeDaekketCount); + + System.out.println("Build: Total Elapsed: " + (stop-start1) ); + System.out.println("Build Completed"); + + } + + + private String calculateExtendedDaoRoute(ExtendedBean eb, Address orgAddress, Address targetAddress) { + + // /////////////////////////////////////////////////////////////////// + switch( eb.transport) { + case "cykel": + if (eb.afstand < 0.151) { + return "." + targetAddress.rute; + } else if (eb.afstand < 0.501) { + return ".." + targetAddress.rute; + } else if (eb.afstand < 0.701) { + return "..." + targetAddress.rute; + } else if (eb.afstand < 0.501) { + return "...." + targetAddress.rute; + } + break; + case "scooter": + if (eb.afstand < 0.151) { + return "." + targetAddress.rute; + } else if (eb.afstand < 0.801) { + return ".." + targetAddress.rute; + } else if (eb.afstand < 1.201) { + return "..." + targetAddress.rute; + } else if (eb.afstand < 2.101) { + return "...." + targetAddress.rute; + } + break; + case "bil": + if (eb.afstand < 0.151) { + return "." + targetAddress.rute; + } else if (eb.afstand < 1.001) { + return ".." + targetAddress.rute; + } else if (eb.afstand < 1.601) { + return "..." + targetAddress.rute; + } else if (eb.afstand < 2.601) { + return "...." + targetAddress.rute; + } + break; + } + return null; + } + + /////////////////////////////////////////////////////////// + private String calculateExtendedBkKoreliste(ExtendedBean eb, Address orgAddress, Address targetAddress) { + String inject; + if (eb.afstand <= 0.500) { + inject = "."; + } else { + inject = ".."; + } + return AddressUtils.injectIntoBk(targetAddress.koreliste, inject); + } + + private Set findVejAliaser(String vejnavn) { + vejnavn = vejnavn.toLowerCase(); + HashSet aliasSet = new HashSet(); + aliasSet.add(vejnavn); + + aliasSet.add(vejnavn.replace("alle", "allé") ); + aliasSet.add(vejnavn.replace("allé", "alle") ); + + aliasSet.add(vejnavn.replace("dronningens", "dr") ); + aliasSet.add(vejnavn.replace("dr.", "dronningens") ); + aliasSet.add(vejnavn.replace("dr ", "dronningens") ); + + aliasSet.add(vejnavn.replace("kvt", "kvarter") ); + aliasSet.add(vejnavn.replace("kvarter", "kvt") ); + + aliasSet.add(vejnavn.replace("gl", "gammel") ); + aliasSet.add(vejnavn.replace("gammel", "gl") ); + + aliasSet.add(vejnavn.replace("lille", "ll") ); + aliasSet.add(vejnavn.replace("ll ", "lille") ); + aliasSet.add(vejnavn.replace("ll.", "lille") ); + + aliasSet.add(vejnavn.replace("store", "st") ); + aliasSet.add(vejnavn.replace("st ", "store") ); + aliasSet.add(vejnavn.replace("st.", "store") ); + + aliasSet.add(vejnavn.replace("søndre", "sdr") ); + aliasSet.add(vejnavn.replace("sdr", "søndre") ); + + + aliasSet.add(vejnavn.replace("nørre", "nr") ); + aliasSet.add(vejnavn.replace("nr", "nørre") ); + + aliasSet.add(vejnavn.replace("nordre", "ndr") ); + aliasSet.add(vejnavn.replace("ndr", "nordre") ); + + aliasSet.add(vejnavn.replace("sankt", "skt") ); + aliasSet.add(vejnavn.replace("sankt", "sct") ); + aliasSet.add(vejnavn.replace("skt", "sankt") ); + + aliasSet.add(vejnavn.replace("skt", "sct") ); + aliasSet.add(vejnavn.replace("sct", "skt") ); + + // Opbyg æøå varianter over alle fundne aliaser + + @SuppressWarnings("unchecked") + HashSet variants = (HashSet) aliasSet.clone(); + + Iterator vIt = variants.iterator(); + while ( vIt.hasNext() ) { + String vVejnavn = vIt.next(); + + // danske tegn 1 + aliasSet.add( vVejnavn.replace("æ", "ae") ); + aliasSet.add( vVejnavn.replace("ø", "oe") ); + aliasSet.add( vVejnavn.replace("å", "aa") ); + aliasSet.add( vVejnavn.replace("ae", "æ") ); + aliasSet.add( vVejnavn.replace("oe", "ø") ); + aliasSet.add( vVejnavn.replace("aa", "å") ); + + //danske tegn 2 + aliasSet.add( vVejnavn.replace("æ", "ae").replace("ø", "oe") ); + aliasSet.add( vVejnavn.replace("æ", "ae").replace("å", "aa") ); + aliasSet.add( vVejnavn.replace("ø", "ae").replace("å", "aa") ); + aliasSet.add( vVejnavn.replace("ae", "æ").replace("oe","ø") ); + aliasSet.add( vVejnavn.replace("ae", "æ").replace("aa","å") ); + aliasSet.add( vVejnavn.replace("oe", "ø").replace("aa", "å") ); + + //danske tegn 3 + aliasSet.add( vejnavn.replace("æ", "ae").replace("ø", "oe").replace("å", "aa") ); + aliasSet.add( vejnavn.replace("ae", "æ").replace("oe", "ø").replace("aa", "å") ); + } + + return aliasSet; + } + + }