From dc24eeb63c58d63366eb6d5038ec067c86581387 Mon Sep 17 00:00:00 2001 From: Pavol Zibrita Date: Fri, 2 Sep 2011 23:55:37 +0200 Subject: [PATCH] Make streets close to each other with same name the same street. --- DataExtractionOSM/OsmAndMapCreator.launch | 2 +- .../data/preparation/IndexAddressCreator.java | 124 ++++++++++++++---- 2 files changed, 97 insertions(+), 29 deletions(-) diff --git a/DataExtractionOSM/OsmAndMapCreator.launch b/DataExtractionOSM/OsmAndMapCreator.launch index c7a3cba55a..c04ea792a9 100644 --- a/DataExtractionOSM/OsmAndMapCreator.launch +++ b/DataExtractionOSM/OsmAndMapCreator.launch @@ -12,5 +12,5 @@ - + diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexAddressCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexAddressCreator.java index 29b57f684f..6ac5d8a44e 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexAddressCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexAddressCreator.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -196,6 +197,23 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{ } } + public static class StreetAndDistrict { + private final Street street; + private final String district; + + StreetAndDistrict(Street street, String district) { + this.street = street; + this.district = district; + } + + public Street getStreet() { + return street; + } + + public String getDistrict() { + return district; + } + } public IndexAddressCreator(){ streetDAO = loadInMemory ? new CachedDBStreetDAO() : new DBStreetDAO(); @@ -820,7 +838,6 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{ writer.startWriteAddressIndex(regionName); List cities = readCities(mapConnection); - List streets = new ArrayList(); Collections.sort(cities, new Comparator() { @Override @@ -887,13 +904,12 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{ writeCities = false; } - streets.clear(); Map> streetNodes = null; if (readWayNodes) { streetNodes = new LinkedHashMap>(); } long time = System.currentTimeMillis(); - readStreetsBuildings(streetstat, c, streets, waynodesStat, streetNodes, listSuburbs); + List streets = readStreetsBuildings(streetstat, c, waynodesStat, streetNodes, listSuburbs); long f = System.currentTimeMillis() - time; writer.writeCityIndex(c, streets, streetNodes); int bCount = 0; @@ -1001,11 +1017,12 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{ stat.close(); } - private List readStreetsBuildings(PreparedStatement streetBuildingsStat, City city, List streets, + private List readStreetsBuildings(PreparedStatement streetBuildingsStat, City city, PreparedStatement waynodesStat, Map> streetNodes, List citySuburbs) throws SQLException { TLongObjectHashMap visitedStreets = new TLongObjectHashMap(); - HashSet uniqueNames = new HashSet(); - + Map> uniqueNames = new HashMap>(); + Map streets = new HashMap(); + //read streets for city readStreatsByBuildingsForCity(streetBuildingsStat, city, streets, waynodesStat, streetNodes, visitedStreets, uniqueNames); @@ -1015,15 +1032,15 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{ readStreatsByBuildingsForCity(streetBuildingsStat, suburb, streets, waynodesStat, streetNodes, visitedStreets, uniqueNames); } } - return streets; + return new ArrayList(streets.values()); } private void readStreatsByBuildingsForCity( PreparedStatement streetBuildingsStat, City city, - List streets, PreparedStatement waynodesStat, + Map streets, PreparedStatement waynodesStat, Map> streetNodes, - TLongObjectHashMap visitedStreets, HashSet uniqueNames) throws SQLException { + TLongObjectHashMap visitedStreets, Map> uniqueNames) throws SQLException { streetBuildingsStat.setLong(1, city.getId()); ResultSet set = streetBuildingsStat.executeQuery(); while (set.next()) { @@ -1031,29 +1048,28 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{ if (!visitedStreets.containsKey(streetId)) { Street street = new Street(null); String streetName = set.getString(2); - String district = ""; - //There are more streets with same name in different districts. - //Add district name to all other names. If sorting is right, the first street was the one in the city - if (uniqueNames.contains(streetName)) { - district = " (" + set.getString(12) + ")"; - } - uniqueNames.add(streetName); - street.setName(streetName + district); - street.setEnName(set.getString(3) + district); street.setLocation(set.getDouble(4), set.getDouble(5)); street.setId(streetId); - streets.add(street); - visitedStreets.put(streetId, street); - if (waynodesStat != null && streetNodes != null) { - ArrayList list = new ArrayList(); - streetNodes.put(street, list); - waynodesStat.setLong(1, street.getId()); - ResultSet rs = waynodesStat.executeQuery(); - while (rs.next()) { - list.add(new Node(rs.getDouble(2), rs.getDouble(3), rs.getLong(1))); + //load the street nodes + loadStreetNodes(street, waynodesStat, streetNodes); + + //If there are more streets with same name in different districts. + //Add district name to all other names. If sorting is right, the first street was the one in the city + String cityPart = " (" + set.getString(12) + ")"; + String district = identifyBestDistrict(street, streetName, cityPart, uniqueNames, streetNodes); + street.setName(streetName + district); + street.setEnName(set.getString(3) + district); + //if for this street there is already same street, add just nodes to the street. + if (!streets.containsKey(street.getName())) { + streets.put(street.getName(),street); + } else { + //add the current streetNodes to the existing street + List firstStreetNodes = streetNodes.get(streets.get(street.getName())); + if (firstStreetNodes != null && streetNodes.get(street) != null) { + firstStreetNodes.addAll(streetNodes.get(street)); } - rs.close(); } + visitedStreets.put(streetId, street); //mark the street as visited } if (set.getObject(6) != null) { Street s = visitedStreets.get(streetId); @@ -1069,6 +1085,58 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{ set.close(); } + + + private void loadStreetNodes(Street street, PreparedStatement waynodesStat, Map> streetNodes) + throws SQLException { + if (waynodesStat != null && streetNodes != null) { + List list = streetNodes.get(street); + if (list == null) { + list = new ArrayList(); + streetNodes.put(street, list); + } + waynodesStat.setLong(1, street.getId()); + ResultSet rs = waynodesStat.executeQuery(); + while (rs.next()) { + list.add(new Node(rs.getDouble(2), rs.getDouble(3), rs.getLong(1))); + } + rs.close(); + } + } + + + private String identifyBestDistrict(final Street street, final String streetName, final String district, + final Map> uniqueNames, Map> streetNodes) { + String result = ""; + List sameStreets = uniqueNames.get(streetName); + if (sameStreets == null) { + sameStreets = new ArrayList(1); + uniqueNames.put(streetName, sameStreets); + } else { + result = district; + // not unique, try to find best matching street with district + // if not found, use the one that is assign to this street + similarStreets: for (StreetAndDistrict ld : sameStreets) { + //try to find the closes nodes to each other! + if (streetNodes != null) { + for (Node n1 : streetNodes.get(street)) { + for (Node n2 : streetNodes.get(ld.getStreet())) { + if (MapUtils.getDistance(n1.getLatLon(), n2.getLatLon()) < 400) { + result = ld.getDistrict(); + break similarStreets; + } + } + } + } + if (MapUtils.getDistance(ld.getStreet().getLocation(), street.getLocation()) < 400) { + result = ld.getDistrict(); + break; + } + } + } + sameStreets.add(new StreetAndDistrict(street, result)); + return result; + } public List readCities(Connection c) throws SQLException{