diff --git a/OsmAnd-java/src/net/osmand/binary/GeocodingUtilities.java b/OsmAnd-java/src/net/osmand/binary/GeocodingUtilities.java index 7a207e6d24..80caea6f90 100644 --- a/OsmAnd-java/src/net/osmand/binary/GeocodingUtilities.java +++ b/OsmAnd-java/src/net/osmand/binary/GeocodingUtilities.java @@ -6,31 +6,29 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; -import java.util.TreeMap; - -import org.apache.commons.logging.Log; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.data.Building; +import net.osmand.data.Building.BuildingInterpolation; import net.osmand.data.City; import net.osmand.data.LatLon; import net.osmand.data.MapObject; import net.osmand.data.Street; import net.osmand.router.BinaryRoutePlanner; -import net.osmand.router.RoutePlannerFrontEnd; -import net.osmand.router.RoutingConfiguration; import net.osmand.router.BinaryRoutePlanner.RouteSegmentPoint; +import net.osmand.router.RoutePlannerFrontEnd; import net.osmand.router.RoutingContext; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; +import org.apache.commons.logging.Log; + public class GeocodingUtilities { private static final Log log = PlatformUtil.getLog(GeocodingUtilities.class); @@ -81,6 +79,7 @@ public class GeocodingUtilities { public String streetName; // justification public Building building; + public String buildingInterpolation; public Street street; public City city; private double dist = -1; @@ -191,7 +190,6 @@ public class GeocodingUtilities { reader.searchAddressDataByName(req); final List res = new ArrayList(); - // FIXME interpolation if(streetsList.size() == 0) { res.add(r); } else { @@ -200,7 +198,42 @@ public class GeocodingUtilities { reader.preloadBuildings(s.street, null); log.info("Preload buildings " + s.street.getName() + " " + s.city.getName() + " " + s.street.getId()); for (Building b : s.street.getBuildings()) { - if (MapUtils.getDistance(b.getLocation(), r.searchPoint) < DISTANCE_BULDING_PROXIMITY) { + if(b.getLatLon2() != null) { + double slat = b.getLocation().getLatitude(); + double slon = b.getLocation().getLongitude(); + double tolat = b.getLatLon2().getLatitude(); + double tolon = b.getLatLon2().getLongitude(); + double coeff = MapUtils.getProjectionCoeff(r.searchPoint.getLatitude(), r.searchPoint.getLongitude(), + slat, slon, tolat, tolon); + double plat = slat + (tolat - slat) * coeff; + double plon = slon + (tolon - slon) * coeff; + if (MapUtils.getDistance(r.searchPoint, plat, plon) < DISTANCE_BULDING_PROXIMITY) { + GeocodingResult bld = new GeocodingResult(s); + bld.building = b; + bld.connectionPoint = b.getLocation(); + streetBuildings.add(bld); + if(!Algorithms.isEmpty(b.getName2())) { + int fi = Algorithms.extractFirstIntegerNumber(b.getName()); + int si = Algorithms.extractFirstIntegerNumber(b.getName2()); + if(si != 0 && fi != 0) { + int num = (int) (fi + (si - fi) * coeff); + BuildingInterpolation type = b.getInterpolationType(); + if(type == BuildingInterpolation.EVEN || type == BuildingInterpolation.ODD) { + if(num % 2 == (type == BuildingInterpolation.EVEN ? 1 : 0)) { + num --; + } + } else if(b.getInterpolationInterval() > 0){ + int intv = b.getInterpolationInterval(); + if ((num - fi) % intv != 0) { + num = ((num - fi) / intv) * intv + fi; + } + } + bld.buildingInterpolation = num +""; + } + } + } + + } else if (MapUtils.getDistance(b.getLocation(), r.searchPoint) < DISTANCE_BULDING_PROXIMITY) { GeocodingResult bld = new GeocodingResult(s); bld.building = b; bld.connectionPoint = b.getLocation(); diff --git a/OsmAnd-java/src/net/osmand/util/MapUtils.java b/OsmAnd-java/src/net/osmand/util/MapUtils.java index f9855eebd3..c3d587e963 100644 --- a/OsmAnd-java/src/net/osmand/util/MapUtils.java +++ b/OsmAnd-java/src/net/osmand/util/MapUtils.java @@ -70,6 +70,21 @@ public class MapUtils { return new LatLon(prlat, prlon); } + public static double getProjectionCoeff(double lat, double lon, double fromLat, double fromLon, double toLat, double toLon) { + // not very accurate computation on sphere but for distances < 1000m it is ok + double mDist = (fromLat - toLat) * (fromLat - toLat) + (fromLon - toLon) * (fromLon - toLon); + double projection = scalarMultiplication(fromLat, fromLon, toLat, toLon, lat, lon); + double prlat; + double prlon; + if (projection < 0) { + return 0; + } else if (projection >= mDist) { + return 1; + } else { + return (projection / mDist); + } + } + private static double toRadians(double angdeg) { // return Math.toRadians(angdeg); return angdeg / 180.0 * Math.PI;