Search in sources :

Example 16 with MapRoad

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;
}
Also used : Int2ObjectOpenHashMap(it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MapRoad(uk.me.parabola.mkgmap.general.MapRoad) Coord(uk.me.parabola.imgfmt.app.Coord) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

MapRoad (uk.me.parabola.mkgmap.general.MapRoad)16 ArrayList (java.util.ArrayList)11 Coord (uk.me.parabola.imgfmt.app.Coord)9 MapLine (uk.me.parabola.mkgmap.general.MapLine)6 MapPoint (uk.me.parabola.mkgmap.general.MapPoint)5 LongArrayList (it.unimi.dsi.fastutil.longs.LongArrayList)4 MapShape (uk.me.parabola.mkgmap.general.MapShape)4 Int2ObjectOpenHashMap (it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 LinkedHashSet (java.util.LinkedHashSet)3 Numbers (uk.me.parabola.imgfmt.app.net.Numbers)3 CityInfo (uk.me.parabola.mkgmap.general.CityInfo)3 Int2IntOpenHashMap (it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap)2 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 CoordNode (uk.me.parabola.imgfmt.app.CoordNode)2 MapExitPoint (uk.me.parabola.mkgmap.general.MapExitPoint)2 MultiHashMap (uk.me.parabola.util.MultiHashMap)2