use of uk.me.parabola.mkgmap.general.MapRoad in project mkgmap by openstreetmap.
the class HousenumberRoad method checkStreetName.
/**
* Check if street name is set, if not, try to find one.
* Identify those houses which are assigned to this road because it was the closest,
* but can't be correct because street name doesn't match.
*
* @param road2HousenumberRoadMap maps {@link MapRoad} instances to corresponding
* {@link HousenumberRoad} instances
* @param nodeId2RoadLists maps node ids to the {@link MapRoad} that use the corresponding nodes.
* @return
*/
public List<HousenumberMatch> checkStreetName(Map<MapRoad, HousenumberRoad> road2HousenumberRoadMap, Int2ObjectOpenHashMap<HashSet<MapRoad>> nodeId2RoadLists) {
List<HousenumberMatch> noWrongHouses = Collections.emptyList();
List<HousenumberMatch> wrongHouses = Collections.emptyList();
double minDist = Double.MAX_VALUE;
double maxDist = 0;
if (houseNumbers.isEmpty() == false) {
HashMap<String, Integer> possibleStreetNamesFromHouses = new HashMap<>();
HashMap<String, Integer> possiblePlaceNamesFromHouses = new HashMap<>();
for (HousenumberMatch house : houseNumbers) {
if (house.getDistance() > maxDist)
maxDist = house.getDistance();
if (house.getDistance() < minDist)
minDist = house.getDistance();
String potentialName = house.getStreet();
if (potentialName != null) {
Integer oldCount = possibleStreetNamesFromHouses.put(potentialName, 1);
if (oldCount != null)
possibleStreetNamesFromHouses.put(potentialName, oldCount + 1);
}
String placeName = house.getPlace();
if (placeName != null) {
Integer oldCount = possiblePlaceNamesFromHouses.put(placeName, 1);
if (oldCount != null)
possiblePlaceNamesFromHouses.put(placeName, oldCount + 1);
}
}
HashSet<String> connectedRoadNames = new HashSet<>();
for (Coord co : road.getPoints()) {
if (co.getId() == 0)
continue;
HashSet<MapRoad> connectedRoads = nodeId2RoadLists.get(co.getId());
for (MapRoad r : connectedRoads) {
if (r.getStreet() != null)
connectedRoadNames.add(r.getStreet());
}
}
if (streetName != null) {
if (possibleStreetNamesFromHouses.isEmpty()) {
// ok, houses have no street name
return noWrongHouses;
}
if (possibleStreetNamesFromHouses.size() == 1) {
if (possibleStreetNamesFromHouses.containsKey(streetName)) {
// ok, houses have same name as street
return noWrongHouses;
}
}
}
if (possibleStreetNamesFromHouses.isEmpty()) {
// neither road not houses tell us a street name
if (furtherNames != null && furtherNames.size() > 0) {
Iterator<String> iter = furtherNames.iterator();
streetName = iter.next();
iter.remove();
if (furtherNames.isEmpty())
furtherNames = null;
}
return noWrongHouses;
}
if (streetName == null) {
if (possibleStreetNamesFromHouses.size() == 1) {
String potentialName = possibleStreetNamesFromHouses.keySet().iterator().next();
boolean nameOK = false;
if (connectedRoadNames.contains(potentialName))
nameOK = true;
else if (houseNumbers.size() > 1) {
nameOK = true;
} else if (maxDist <= 10) {
nameOK = true;
}
if (nameOK) {
streetName = potentialName;
// all good, return empty list
return noWrongHouses;
}
} else {
List<String> matchingNames = new ArrayList<>();
for (Entry<String, Integer> entry : possibleStreetNamesFromHouses.entrySet()) {
String name = entry.getKey();
if (connectedRoadNames.contains(name)) {
matchingNames.add(name);
}
}
if (matchingNames.size() == 1) {
streetName = matchingNames.get(0);
}
}
}
// if we get here we have no usable street name
wrongHouses = new ArrayList<>();
Iterator<HousenumberMatch> iter = houseNumbers.iterator();
while (iter.hasNext()) {
HousenumberMatch house = iter.next();
if (streetName != null) {
if (house.getStreet() == null || streetName.equalsIgnoreCase(house.getStreet()))
continue;
} else if (house.getPlace() != null)
continue;
double bestDist = Double.MAX_VALUE;
HousenumberMatch best = null;
for (MapRoad altRoad : house.getAlternativeRoads()) {
if (house.getStreet() != null) {
if (house.getStreet().equals(altRoad.getStreet())) {
HousenumberMatch test = new HousenumberMatch(house);
HousenumberGenerator.findClosestRoadSegment(test, altRoad);
if (test.getDistance() < bestDist) {
best = test;
bestDist = test.getDistance();
}
}
}
}
iter.remove();
if (best != null) {
best.calcRoadSide();
wrongHouses.add(best);
} else {
log.warn("found no plausible road for address", house.getStreet(), house, house.toBrowseURL());
}
}
}
return wrongHouses;
}
Aggregations