--- dao/DaoAdresseService/src/dk/daoas/daoadresseservice/AdressSearch.java 2015/02/26 10:26:01 2380 +++ dao/DaoAdresseService/src/main/java/dk/daoas/daoadresseservice/AddressSearch.java 2015/03/24 12:38:21 2490 @@ -9,60 +9,78 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.lang3.StringUtils; + import dk.daoas.daoadresseservice.admin.ServiceConfig; import dk.daoas.daoadresseservice.beans.Address; +import dk.daoas.daoadresseservice.beans.AliasBean; import dk.daoas.daoadresseservice.beans.DataStatisticsBean; import dk.daoas.daoadresseservice.beans.ExtendedBean; import dk.daoas.daoadresseservice.beans.HundredePctBean; +import dk.daoas.daoadresseservice.beans.SearchRequest; import dk.daoas.daoadresseservice.beans.SearchResult; import dk.daoas.daoadresseservice.beans.SearchResult.Status; import dk.daoas.daoadresseservice.db.DatabaseLayer; -public class AdressSearch { +public class AddressSearch { - private Map> searchPostnrVejnavnGadeid; - private Map> searchGadeidentAdresser; + private Map> searchPostnrVejnavnGadeid; + private Map> searchGadeidentAdresser; private List
alleAdresser; - private Map helperCache; + private Map helperCache; private DataStatisticsBean stats = new DataStatisticsBean(); ServiceConfig config; - public AdressSearch(ServiceConfig config) { + StreetnameHelper levenshteinHelper; + StreetnameHelper googleHelper; + StreetnameHelper osmHelper; + + + public AddressSearch(ServiceConfig config) { this.config = config; + + levenshteinHelper = new LevenshteinStreetnameHelper( this ); + googleHelper = new GoogleStreetnameHelper( config ); + osmHelper = new OSMStreetnameHelper( config ); } public SearchResult search(String postnrStr, String adresse) { - + SearchRequest request = new SearchRequest(); SearchResult result = new SearchResult(); - int postnr=0; String helperSearchKey = ""; try { - postnr = Integer.parseInt(postnrStr); + request.postnr = Integer.parseInt(postnrStr); } catch (Exception E) { result.status = Status.ERROR_UNKNOWN_POSTAL; return result; } - Map postnrVeje = searchPostnrVejnavnGadeid.get(postnr); - if (postnrVeje == null) { + request.streetNames = searchPostnrVejnavnGadeid.get(request.postnr); + + if (request.streetNames == null) { result.status = Status.ERROR_UNKNOWN_POSTAL; return result; } result.splitResult = AddressUtils.splitAdresse(adresse); + request.vejnavn = result.splitResult.vej; + if (result.splitResult.husnr.length() == 0) { @@ -70,54 +88,56 @@ return result; } - String vasketVejnavn = AddressUtils.vaskVejnavn( result.splitResult.vej ); + request.vasketVejnavn = AddressUtils.vaskVejnavn( request.vejnavn ); + + + if (request.vasketVejnavn.indexOf("pakkebo") > -1 + || request.vasketVejnavn.indexOf("døgnpost") > -1 + || request.vasketVejnavn.indexOf("døgnbo") > -1 + || request.vasketVejnavn.equals("id") + ) { + result.status = Status.ERROR_POSTBOX; + return result; + } - Long gadeident = postnrVeje.get(vasketVejnavn); + Integer gadeident = request.streetNames.get(request.vasketVejnavn); if ( gadeident == null) { - helperSearchKey = "" + postnr + "/" + vasketVejnavn; + helperSearchKey = "" + request.postnr + "/" + request.vasketVejnavn; gadeident = helperCache.get(helperSearchKey); } + if (gadeident == null) { + String vej = levenshteinHelper.proposeStreetName(request, result); + if (vej != null) { + gadeident = request.streetNames.get(vej); + } + } + + // Brug OpenStreetMap før vi prøver google + // For google har en request limit, det har OSM ikke! if ( gadeident == null) { - if (config.useGoogle) { - result.googleVej = GeocodeHelper.googleHelper(config, postnr, result.splitResult.vej ); - result.google = true; - - if (result.googleVej != null) { - String googleVasket = AddressUtils.vaskVejnavn( result.googleVej ); - gadeident = postnrVeje.get(googleVasket); - - if (gadeident != null) { - helperCache.put(helperSearchKey, gadeident); - } - } - } + String vej = osmHelper.proposeStreetName(request, result); + gadeident = helperWrapper(vej, request.streetNames, helperSearchKey); } if ( gadeident == null) { - if (config.useOpenStreetMaps) { - result.osmVej = GeocodeHelper.openstreetmapHelper(config, postnr, result.splitResult.vej ); - result.osm = true; - - if (result.osmVej != null) { - String osmVasket = AddressUtils.vaskVejnavn( result.osmVej ); - gadeident = postnrVeje.get(osmVasket); - - if (gadeident != null) { - helperCache.put(helperSearchKey, gadeident); - } - } - } + String vej = googleHelper.proposeStreetName(request, result); + gadeident = helperWrapper(vej, request.streetNames, helperSearchKey); } + + if (gadeident == null) { result.status = Status.ERROR_UNKNOWN_STREETNAME; return result; } + result.gadeident = gadeident; + + Map gade = searchGadeidentAdresser.get(gadeident); if (gade == null) { //Denne søgning må ikke fejle result.status = Status.ERROR_INTERNAL; @@ -125,6 +145,10 @@ } + //Kunne evt klares med Iterables.get fra Guava/Collections + Address firstAddress = gade.values().iterator().next(); + result.vej = firstAddress.vejnavn; + String husnrSearch = "" + result.splitResult.husnr + result.splitResult.litra; Address addr = gade.get(husnrSearch); @@ -135,7 +159,8 @@ result.address = addr; - if (addr.distributor != null && addr.distributor.equals("LUKKET")) { + + if ( StringUtils.equals(addr.distributor, "LUKKET") ) { result.status = Status.STATUS_NOT_COVERED; //Skal vi have en special status til Lukkede adresser ? return result; } @@ -151,11 +176,30 @@ return result; } + private Integer helperWrapper(String vej, Map postnrVeje, String helperSearchKey) { + if (vej == null) + return null; + + String vejVasket = AddressUtils.vaskVejnavn( vej ); + Integer gadeident = postnrVeje.get(vejVasket); + + if (gadeident != null) { + helperCache.put(helperSearchKey, gadeident); + } + return gadeident; + + } + + public Map getStretsByPostal(int zip) { + return searchPostnrVejnavnGadeid.get(zip); + } + + public void buildSearchStructures() throws SQLException{ - searchPostnrVejnavnGadeid = new HashMap>(); - searchGadeidentAdresser = new HashMap>(); - helperCache = new ConcurrentHashMap(); + searchPostnrVejnavnGadeid = new HashMap>(); + searchGadeidentAdresser = new HashMap>(); + helperCache = new ConcurrentHashMap(); long start1 = System.currentTimeMillis(); System.out.println("Build -- stage 1"); @@ -169,40 +213,75 @@ for (Address a : alleAdresser) { idAddressMap.put(a.id, a); - Map postnrVeje = searchPostnrVejnavnGadeid.get(a.postnr); + Map postnrVeje = searchPostnrVejnavnGadeid.get(a.postnr); if (postnrVeje == null) { - postnrVeje = new ConcurrentHashMap(); + postnrVeje = new ConcurrentHashMap(); searchPostnrVejnavnGadeid.put(a.postnr, postnrVeje); } String vasketVejnavn = AddressUtils.vaskVejnavn(a.vejnavn); - Long gadeident = postnrVeje.get(vasketVejnavn); - if (gadeident == null) { + Integer gadeident = postnrVeje.get(vasketVejnavn); + if (gadeident == null) { //postnrVeje.put(vasketVejnavn, a.gadeid); + gadeident = a.gadeid; + Set aliaser = findVejAliaser(a.vejnavn); for(String alias : aliaser) { String vasketAlias = AddressUtils.vaskVejnavn(alias); - postnrVeje.put(vasketAlias, a.gadeid); - } - + postnrVeje.put(vasketAlias, gadeident); + } } - Map gade = searchGadeidentAdresser.get(a.gadeid); + Map gade = searchGadeidentAdresser.get(gadeident); if (gade == null) { gade = new HashMap(); - searchGadeidentAdresser.put(a.gadeid, gade); + searchGadeidentAdresser.put(gadeident, 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"); + System.out.println("Build -- stage 2 alias tabel"); + + int vaskCount = 0; + List aliasList = DatabaseLayer.getAliasList(); + for (AliasBean alias : aliasList) { + Map postnrVeje = searchPostnrVejnavnGadeid.get(alias.postnr); + + if (postnrVeje == null) { + //Burde ikke kunne ske - men better safe than sorry + continue; + } + + String vasketVej = AddressUtils.vaskVejnavn(alias.vejnavn); + String vasketAlias = AddressUtils.vaskVejnavn(alias.aliasVejnavn); + + Integer gadeident = postnrVeje.get(vasketVej); + if (gadeident == null) { + //Kender ikke den oprindelige vej + continue; + } + + Integer aliasIdent = postnrVeje.get(vasketAlias); + + if (aliasIdent == null) { //Vi kender ikke denne variant af vejnavnet + postnrVeje.put(vasketAlias, gadeident); + vaskCount++; + } + + } + System.out.println("Anvendte " + vaskCount + " aliaser fra databasen"); + + + //////////////////////////////////////////////////////////////////////////////////////// + long start3 = System.currentTimeMillis(); + System.out.println("Build, stage2 elapsed: " + (start3-start2) ); + System.out.println("Build -- stage 3 udvidet dækning"); List extDao = DatabaseLayer.getExtendedAdresslist(); for (ExtendedBean eb : extDao) { @@ -259,9 +338,9 @@ idAddressMap = null; ////////////////////////////////////////////////////////////////////////////////////// - long start3 = System.currentTimeMillis(); - System.out.println("Build, stage2 elapsed: " + (start3-start2) ); - System.out.println("Build -- stage 3 - 100pct"); + long start4 = System.currentTimeMillis(); + System.out.println("Build, stage3 elapsed: " + (start4-start3) ); + System.out.println("Build -- stage 4 - 100pct"); Map hundredePct = DatabaseLayer.get100PctList(); for (Address addr : alleAdresser) { @@ -288,7 +367,7 @@ //////////////////////////////////////////////////////////////////////////////////// long stop = System.currentTimeMillis(); - System.out.println("Build, stage3 elapsed: " + (stop-start3) ); + System.out.println("Build, stage3 elapsed: " + (stop-start4) ); System.out.println("Build -- Gathering statistics"); for (Address addr : alleAdresser) { @@ -334,6 +413,9 @@ private String calculateExtendedDaoRoute(ExtendedBean eb, Address orgAddress, Address targetAddress) { + if (targetAddress.rute == null) { //hvis targetAdress.rute er null så er adressen ikke dækket alligevel + return null; + } // /////////////////////////////////////////////////////////////////// switch( eb.transport) { @@ -411,6 +493,13 @@ aliasSet.add(vejnavn.replace("dr.", "dronningens") ); aliasSet.add(vejnavn.replace("dr ", "dronningens") ); + aliasSet.add(vejnavn.replace("dronning", "dr") ); + aliasSet.add(vejnavn.replace("dr.", "dronning") ); + aliasSet.add(vejnavn.replace("dr ", "dronning") ); + + aliasSet.add(vejnavn.replace("kng", "kongen") ); + aliasSet.add(vejnavn.replace("kongen", "kng") ); + aliasSet.add(vejnavn.replace("kvt", "kvarter") ); aliasSet.add(vejnavn.replace("kvarter", "kvt") ); @@ -443,14 +532,61 @@ aliasSet.add(vejnavn.replace("sct", "skt") ); + // fornavn forkortelser + aliasSet.add(vejnavn.replace("john", "j") ); + aliasSet.add(vejnavn.replace("thomas", "th") ); + aliasSet.add(vejnavn.replace("thorvald", "th") ); + + + // Romertal + aliasSet.add(vejnavn.replace("1", "i") ); + aliasSet.add(vejnavn.replace("i", "1") ); + + aliasSet.add(vejnavn.replace("2", "ii") ); + aliasSet.add(vejnavn.replace("ii", "2") ); + + aliasSet.add(vejnavn.replace("3", "iii") ); + aliasSet.add(vejnavn.replace("iii", "3") ); + + aliasSet.add(vejnavn.replace("4", "iv") ); + aliasSet.add(vejnavn.replace("iv", "4") ); + + aliasSet.add(vejnavn.replace("5", "v") ); + aliasSet.add(vejnavn.replace("v", "5") ); + + aliasSet.add(vejnavn.replace("6", "vi") ); + aliasSet.add(vejnavn.replace("vi", "6") ); + + aliasSet.add(vejnavn.replace("7", "vii") ); + aliasSet.add(vejnavn.replace("vii", "7") ); + + aliasSet.add(vejnavn.replace("8", "viii") ); + aliasSet.add(vejnavn.replace("viii", "8") ); + + aliasSet.add(vejnavn.replace("9", "ix") ); + aliasSet.add(vejnavn.replace("ix", "9") ); + + aliasSet.add(vejnavn.replace("10", "x") ); + aliasSet.add(vejnavn.replace("x", "10") ); + + //alternative måder at stave vej/gade/alle aliasSet.add(vejnavn.replace("vej", "ve") ); aliasSet.add(vejnavn.replace("vej", "vj") ); + aliasSet.add(vejnavn.replace("vej", "v") ); + aliasSet.add(vejnavn.replace("vej", "vejen") ); + aliasSet.add(vejnavn.replace("vejen", "vej") ); aliasSet.add(vejnavn.replace("alle", "all") ); aliasSet.add(vejnavn.replace("allé", "all") ); + aliasSet.add(vejnavn.replace("alle", "allú") ); //Fundet i logs.hentruteinfo + aliasSet.add(vejnavn.replace("allé", "allú") ); - aliasSet.add(vejnavn.replace("gade", "gaed") ); + aliasSet.add(vejnavn.replace("gade", "gaed") ); //Fundet i logs.hentruteinfo + aliasSet.add(vejnavn.replace("gade", "gde") ); + + aliasSet.add(vejnavn.replace("plads", "pl") ); + aliasSet.add(vejnavn.replace("vænget", "vænge") ); // Opbyg æøå varianter over alle fundne aliaser @@ -470,7 +606,7 @@ //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("ø", "oe").replace("å", "aa") ); aliasSet.add( vVejnavn.replace("ae", "æ").replace("oe","ø") ); aliasSet.add( vVejnavn.replace("ae", "æ").replace("aa","å") ); aliasSet.add( vVejnavn.replace("oe", "ø").replace("aa", "å") ); @@ -483,5 +619,31 @@ return aliasSet; } + public Set getPostnumre() { + return new TreeSet( searchPostnrVejnavnGadeid.keySet() ); + } + + public Set> getVejnavne(int postnr) { + Map map = searchPostnrVejnavnGadeid.get(postnr); + TreeMap newMap = new TreeMap(); + for (Entry entry : map.entrySet() ) { + newMap.put(entry.getKey(), entry.getValue()); + } + + return newMap.entrySet(); + } + public Set getHusnumre(long gadeid) { + + Map gade = searchGadeidentAdresser.get(gadeid); + return new TreeSet( gade.keySet() ); + } + + public Address getAdresse(long gadeid, String husnr) { + + Map gade = searchGadeidentAdresser.get(gadeid); + return gade.get(husnr); + + } + }