Improve geocoing

This commit is contained in:
Victor Shcherb 2015-11-29 15:20:36 +01:00
parent 8df21aa29a
commit 899ca53231
11 changed files with 451 additions and 54 deletions

View file

@ -594,6 +594,7 @@ public class BinaryMapAddressReaderAdapter {
int old = codedIS.pushLimit(len);
LatLon l = obj.getLocation();
Street s = new Street(obj);
s.setFileOffset(list.get(j));
readStreet(s, null, false, MapUtils.get31TileNumberX(l.getLongitude()) >> 7,
MapUtils.get31TileNumberY(l.getLatitude()) >> 7, obj.isPostcode() ? obj.getName() : null,
reg.attributeTagsTable);

View file

@ -21,10 +21,12 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@ -1951,7 +1953,8 @@ public class BinaryMapIndexReader {
private static boolean testMapSearch = false;
private static boolean testAddressSearch = false;
private static boolean testPoiSearch = true;
private static boolean testAddressJustifySearch = true;
private static boolean testPoiSearch = false;
private static boolean testPoiSearchOnPath = false;
private static boolean testTransportSearch = false;
private static int sleft = MapUtils.get31TileNumberX(6.3);
@ -1965,7 +1968,8 @@ public class BinaryMapIndexReader {
}
public static void main(String[] args) throws IOException {
File fl = new File("/Users/victorshcherb/osmand/maps/Synthetic_test_rendering.obf");
// File fl = new File("/Users/victorshcherb/osmand/maps/Synthetic_test_rendering.obf");
File fl = new File("/Users/victorshcherb/osmand/maps/Netherlands_europe_2.road.obf");
RandomAccessFile raf = new RandomAccessFile(fl, "r");
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf, fl);
@ -1979,6 +1983,9 @@ public class BinaryMapIndexReader {
testAddressSearchByName(reader);
testAddressSearch(reader);
}
if(testAddressJustifySearch) {
testAddressJustifySearch(reader);
}
if(testTransportSearch) {
testTransportSearch(reader);
}
@ -2259,6 +2266,71 @@ public class BinaryMapIndexReader {
reader.searchAddressDataByName(req);
}
/**
* @param reader
* @throws IOException
*/
/**
* @param reader
* @throws IOException
*/
private static void testAddressJustifySearch(BinaryMapIndexReader reader) throws IOException {
final String streetName = "Logger";
final double lat = 52.28212d;
final double lon = 4.86269d;
// test address index search
final List<Street> streetsList = new ArrayList<Street>();
SearchRequest<MapObject> req = buildAddressByNameRequest(new ResultMatcher<MapObject>() {
@Override
public boolean publish(MapObject object) {
if(object instanceof Street && object.getName().equalsIgnoreCase(streetName)) {
if(MapUtils.getDistance(object.getLocation(), lat, lon) < 20000) {
streetsList.add((Street) object);
return true;
}
return false;
}
return false;
}
@Override
public boolean isCancelled() {
return false;
}
}, streetName);
reader.searchAddressDataByName(req);
TreeMap<MapObject, Street> resMap = new TreeMap<MapObject, Street>(new Comparator<MapObject>() {
@Override
public int compare(MapObject o1, MapObject o2) {
LatLon l1 = o1.getLocation();
LatLon l2 = o2.getLocation();
if(l1 == null || l2 == null){
return l2 == l1 ? 0 : (l1 == null ? -1 : 1);
}
return Double.compare(MapUtils.getDistance(l1, lat, lon), MapUtils.getDistance(l2, lat, lon));
}
});
for(Street s : streetsList) {
resMap.put(s, s);
reader.preloadBuildings(s, null);
for(Building b : s.getBuildings()) {
if(MapUtils.getDistance(b.getLocation(), lat, lon) < 100) {
resMap.put(b, s);
}
}
}
for(MapObject e : resMap.keySet()) {
Street s = resMap.get(e);
if(e instanceof Building && MapUtils.getDistance(e.getLocation(), lat, lon) < 40) {
Building b = (Building) e;
System.out.println(b.getName() + " " + s);
} else if(e instanceof Street){
System.out.println(s + " " + ((Street) s).getCity());
}
}
}
private static void testAddressSearch(BinaryMapIndexReader reader) throws IOException {
// test address index search
final Map<String, Integer> streetFreq = new HashMap<String, Integer>();

View file

@ -215,6 +215,7 @@ public class BinaryMapRouteReaderAdapter {
int destinationTypeRule = -1;
int destinationRefTypeRule = -1;
public RouteTypeRule quickGetEncodingRule(int id) {
return routeEncodingRules.get(id);
}

View file

@ -0,0 +1,228 @@
package net.osmand.binary;
import gnu.trove.set.hash.TLongHashSet;
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.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.RoutingContext;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
public class GeocodingUtilities {
private static final Log log = PlatformUtil.getLog(GeocodingUtilities.class);
public static final float THRESHOLD_MULTIPLIER_SKIP_BUILDINGS_AFTER = 1.5f;
public static final float THRESHOLD_MULTIPLIER_SKIP_STREETS_AFTER = 3;
public static final float DISTANCE_STREET_NAME_PROXIMITY_BY_NAME = 20000;
public static final float DISTANCE_BULDING_PROXIMITY = 100;
public static final float THRESHOLD_STREET_CHANGE_CONNECTION_POINT = 400; // not important
public static final Comparator<GeocodingResult> DISTANCE_COMPARATOR = new Comparator<GeocodingResult>() {
@Override
public int compare(GeocodingResult o1, GeocodingResult o2) {
LatLon l1 = o1.getLocation();
LatLon l2 = o2.getLocation();
if(l1 == null || l2 == null){
return l2 == l1 ? 0 : (l1 == null ? -1 : 1);
}
return Double.compare(MapUtils.getDistance(l1, o1.searchPoint),
MapUtils.getDistance(l2, o2.searchPoint));
}
};
public static class GeocodingResult {
public GeocodingResult(){
}
public GeocodingResult(GeocodingResult r){
this.searchPoint = r.searchPoint;
this.regionFP = r.regionFP;
this.regionLen = r.regionLen;
this.connectionPoint = r.connectionPoint;
this.streetName = r.streetName;
this.point = r.point;
this.building = r.building;
this.city = r.city;
this.street = r.street;
this.streetName = r.streetName;
}
// input
public LatLon searchPoint;
// 1st step
public LatLon connectionPoint;
public int regionFP;
public int regionLen;
public RouteSegmentPoint point;
public String streetName;
// justification
public Building building;
public Street street;
public City city;
private double dist = -1;
public LatLon getLocation() {
return connectionPoint;
}
public double getDistance() {
if(dist == -1) {
dist = MapUtils.getDistance(connectionPoint, searchPoint);
}
return dist;
}
@Override
public String toString() {
StringBuilder bld = new StringBuilder();
if(building != null) {
bld.append(building.getName());
}
if(street != null) {
bld.append(" str. ").append(street.getName()).append(" city ").append(city.getName());
} else if(streetName != null) {
bld.append(" str. ").append(streetName);
} else if(city != null) {
bld.append(" city ").append(city.getName());
}
if(connectionPoint != null && searchPoint != null) {
bld.append(" dist=").append((int) getDistance());
}
return bld.toString();
}
}
public List<GeocodingResult> reverseGeocodingSearch(RoutingContext ctx, double lat, double lon) throws IOException {
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd(false);
List<GeocodingResult> lst = new ArrayList<GeocodingUtilities.GeocodingResult>();
List<RouteSegmentPoint> listR = new ArrayList<BinaryRoutePlanner.RouteSegmentPoint>();
rp.findRouteSegment(lat, lon, ctx, listR);
double dist = 0;
TLongHashSet set = new TLongHashSet();
Set<String> streetNames = new HashSet<String>();
for(RouteSegmentPoint p : listR) {
RouteDataObject road = p.getRoad();
if(!set.add(road.getId())) {
continue;
}
boolean emptyName = Algorithms.isEmpty(road.getName()) && Algorithms.isEmpty(road.getRef()) ;
if(!emptyName) {
if(dist == 0) {
dist = p.dist;
}
GeocodingResult sr = new GeocodingResult();
sr.searchPoint = new LatLon(lat, lon);
sr.streetName = Algorithms.isEmpty(road.getName())? road.getRef() : road.getName();
sr.point = p;
sr.connectionPoint = new LatLon(MapUtils.get31LatitudeY(p.preciseY), MapUtils.get31LongitudeX(p.preciseX));
sr.regionFP = road.region.getFilePointer();
sr.regionLen = road.region.getLength();
if(streetNames.add(sr.streetName)) {
lst.add(sr);
}
}
if(p.dist > 100*100 && dist != 0 && p.dist > 4 * dist ) {
break;
}
if(p.dist > 300*300) {
break;
}
}
Collections.sort(lst, GeocodingUtilities.DISTANCE_COMPARATOR);
return lst;
}
public List<GeocodingResult> justifyReverseGeocodingSearch(final GeocodingResult r, BinaryMapIndexReader reader,
double knownMinBuidlingDistance) throws IOException {
// test address index search
final List<GeocodingResult> streetsList = new ArrayList<GeocodingResult>();
log.info("Search street by name " + r.streetName);
SearchRequest<MapObject> req = BinaryMapIndexReader.buildAddressByNameRequest(new ResultMatcher<MapObject>() {
@Override
public boolean publish(MapObject object) {
if(object instanceof Street && object.getName().equalsIgnoreCase(r.streetName)) {
double d = MapUtils.getDistance(object.getLocation(), r.searchPoint.getLatitude(),
r.searchPoint.getLongitude());
if(d < DISTANCE_STREET_NAME_PROXIMITY_BY_NAME) {
GeocodingResult rs = new GeocodingResult(r);
rs.street = (Street) object;
rs.city = rs.street.getCity();
if(d > THRESHOLD_STREET_CHANGE_CONNECTION_POINT) {
rs.connectionPoint = rs.street.getLocation();
}
streetsList.add(rs);
return true;
}
return false;
}
return false;
}
@Override
public boolean isCancelled() {
return false;
}
}, r.streetName);
reader.searchAddressDataByName(req);
final List<GeocodingResult> res = new ArrayList<GeocodingResult>();
// FIXME interpolation
for(GeocodingResult s : streetsList) {
final List<GeocodingResult> streetBuildings = new ArrayList<GeocodingResult>();
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) {
GeocodingResult bld = new GeocodingResult(s);
bld.building = b;
bld.connectionPoint = b.getLocation();
streetBuildings.add(bld);
}
}
Collections.sort(streetBuildings, DISTANCE_COMPARATOR);
if(streetBuildings.size() > 0) {
Iterator<GeocodingResult> it = streetBuildings.iterator();
if(knownMinBuidlingDistance == 0) {
GeocodingResult firstBld = it.next();
knownMinBuidlingDistance = firstBld.getDistance();
res.add(firstBld);
}
while(it.hasNext()) {
GeocodingResult nextBld = it.next();
if(nextBld.getDistance() > knownMinBuidlingDistance * THRESHOLD_MULTIPLIER_SKIP_BUILDINGS_AFTER) {
break;
}
res.add(nextBld);
}
}
res.add(s);
}
Collections.sort(res, DISTANCE_COMPARATOR);
return res;
}
}

View file

@ -55,7 +55,7 @@ public class RoutePlannerFrontEnd {
return dx * dx + dy * dy;
}
public RouteSegmentPoint findRouteSegment(double lat, double lon, boolean searchWithName, RoutingContext ctx) throws IOException {
public RouteSegmentPoint findRouteSegment(double lat, double lon, RoutingContext ctx, List<RouteSegmentPoint> list) throws IOException {
int px = MapUtils.get31TileNumberX(lon);
int py = MapUtils.get31TileNumberY(lat);
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
@ -63,12 +63,10 @@ public class RoutePlannerFrontEnd {
if (dataObjects.isEmpty()) {
ctx.loadTileData(px, py, 15, dataObjects);
}
List<RouteSegmentPoint> list = new ArrayList<BinaryRoutePlanner.RouteSegmentPoint>();
if(list == null) {
list = new ArrayList<BinaryRoutePlanner.RouteSegmentPoint>();
}
for (RouteDataObject r : dataObjects) {
boolean emptyName = Algorithms.isEmpty(r.getName()) && Algorithms.isEmpty(r.getRef()) ;
if(searchWithName && emptyName) {
continue;
}
if (r.getPointsLength() > 1) {
RouteSegmentPoint road = null;
for (int j = 1; j < r.getPointsLength(); j++) {
@ -95,7 +93,7 @@ public class RoutePlannerFrontEnd {
}
});
if(list.size() > 0) {
RouteSegmentPoint ps = list.remove(0);
RouteSegmentPoint ps = list.get(0);
ps.others = list;
return ps;
}
@ -284,7 +282,7 @@ public class RoutePlannerFrontEnd {
}
private boolean addSegment(LatLon s, RoutingContext ctx, int indexNotFound, List<RouteSegmentPoint> res) throws IOException {
RouteSegmentPoint f = findRouteSegment(s.getLatitude(), s.getLongitude(), false, ctx);
RouteSegmentPoint f = findRouteSegment(s.getLatitude(), s.getLongitude(), ctx, null);
if(f == null){
ctx.calculationProgress.segmentNotFound = indexNotFound;
return false;

View file

@ -310,8 +310,8 @@ public class TestRouting {
RoutingConfiguration rconfig = config.build(vehicle, MEMORY_TEST_LIMIT);
RoutePlannerFrontEnd router = new RoutePlannerFrontEnd(oldRouting);
RoutingContext ctx = router.buildRoutingContext(rconfig, lib, rs);
RouteSegment startSegment = router.findRouteSegment(startLat, startLon, false, ctx);
RouteSegment endSegment = router.findRouteSegment(endLat, endLon, false, ctx);
RouteSegment startSegment = router.findRouteSegment(startLat, startLon, ctx, null);
RouteSegment endSegment = router.findRouteSegment(endLat, endLon, ctx, null);
if(startSegment == null){
throw new IllegalArgumentException("Start segment is not found ");
}

View file

@ -1,11 +1,22 @@
package net.osmand.plus;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import net.osmand.Location;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.GeocodingUtilities;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.GeocodingUtilities.GeocodingResult;
import net.osmand.binary.RouteDataObject;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.OSMSettings.OSMTagKey;
import net.osmand.plus.resources.RegionAddressRepository;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.BinaryRoutePlanner.RouteSegmentPoint;
import net.osmand.router.GeneralRouter.GeneralRouterProfile;
@ -46,16 +57,25 @@ public class CurrentPositionHelper {
private void scheduleRouteSegmentFind(final Location loc, final ResultMatcher<RouteDataObject> result, final boolean storeFound) {
private void scheduleRouteSegmentFind(final Location loc, final boolean storeFound, final ResultMatcher<GeocodingResult> geoCoding, final ResultMatcher<RouteDataObject> result) {
if (loc != null) {
Runnable run = new Runnable() {
@Override
public void run() {
try {
RouteDataObject res = runUpdateInThread(loc.getLatitude(), loc.getLongitude(), result);
final List<GeocodingResult> gr = runUpdateInThread(loc.getLatitude(), loc.getLongitude());
if (storeFound) {
lastAskedLocation = loc;
lastFound = res;
lastFound = gr.isEmpty() ? null : gr.get(0).point.getRoad();
} else if(geoCoding != null) {
justifyResult(gr, geoCoding);
} else if(result != null) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
result.publish(gr.isEmpty() ? null : gr.get(0).point.getRoad());
}
});
}
} catch (IOException e) {
e.printStackTrace();
@ -66,6 +86,59 @@ public class CurrentPositionHelper {
}
}
protected void justifyResult(List<GeocodingResult> res, final ResultMatcher<GeocodingResult> result) {
double minBuildingDistance = 0;
List<GeocodingResult> complete = new ArrayList<GeocodingUtilities.GeocodingResult>();
for (GeocodingResult r : res) {
if (minBuildingDistance > 0
&& r.getDistance() > GeocodingUtilities.THRESHOLD_MULTIPLIER_SKIP_STREETS_AFTER * minBuildingDistance) {
break;
}
Collection<RegionAddressRepository> rar = app.getResourceManager().getAddressRepositories();
RegionAddressRepository foundRepo = null;
for(RegionAddressRepository repo : rar) {
BinaryMapIndexReader reader = repo.getFile();
for (RouteRegion rb : reader.getRoutingIndexes()) {
if (r.regionFP == rb.getFilePointer() && r.regionLen == rb.getLength()) {
foundRepo = repo;
break;
}
}
if(foundRepo != null) {
break;
}
}
if (foundRepo != null) {
List<GeocodingResult> justified = foundRepo.justifyReverseGeocodingSearch(r, minBuildingDistance);
if(!justified.isEmpty()) {
double md = justified.get(0).getDistance();
if(minBuildingDistance == 0){
minBuildingDistance = md;
} else {
minBuildingDistance = Math.min(md, minBuildingDistance);
}
complete.addAll(justified);
}
} else {
complete.add(r);
}
}
Collections.sort(complete, GeocodingUtilities.DISTANCE_COMPARATOR);
for(final GeocodingResult r : complete) {
if(r.building != null &&
r.getDistance() > minBuildingDistance * GeocodingUtilities.THRESHOLD_MULTIPLIER_SKIP_BUILDINGS_AFTER) {
continue;
}
app.runInUIThread(new Runnable() {
public void run() {
result.publish(r);
}
});
break;
}
}
private static double getOrthogonalDistance(RouteDataObject r, Location loc){
double d = 1000;
if (r.getPointsLength() > 0) {
@ -86,7 +159,11 @@ public class CurrentPositionHelper {
}
public void getRouteSegment(Location loc, ResultMatcher<RouteDataObject> result) {
scheduleRouteSegmentFind(loc, result, false);
scheduleRouteSegmentFind(loc, false, null, result);
}
public void getGeocodingResult(Location loc, ResultMatcher<GeocodingResult> result) {
scheduleRouteSegmentFind(loc, false, result, null);
}
public RouteDataObject getLastKnownRouteSegment(Location loc) {
@ -99,12 +176,12 @@ public class CurrentPositionHelper {
return r;
}
if (r == null) {
scheduleRouteSegmentFind(loc, null, true);
scheduleRouteSegmentFind(loc, true, null, null);
return null;
}
double d = getOrthogonalDistance(r, loc);
if (d > 25) {
scheduleRouteSegmentFind(loc, null, true);
scheduleRouteSegmentFind(loc, true, null, null);
}
if (d < 70) {
return r;
@ -113,34 +190,13 @@ public class CurrentPositionHelper {
}
private synchronized RouteDataObject runUpdateInThread(double lat, double lon, final ResultMatcher<RouteDataObject> resultMatcher) throws IOException {
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd(false);
private synchronized List<GeocodingResult> runUpdateInThread(double lat, double lon) throws IOException {
if (ctx == null || am != app.getSettings().getApplicationMode()) {
initCtx(app);
if (ctx == null) {
return null;
}
}
final RouteSegmentPoint sg = rp.findRouteSegment(lat, lon, true, ctx);
final RouteDataObject res;
if(sg == null) {
res = null;
} else {
RouteSegmentPoint ff = rp.findRouteSegment(lat, lon, false, ctx);
if(ff == null || ff.dist + 70 * 70 < sg.dist) {
res = null;
} else {
res = sg.getRoad();
}
}
if(resultMatcher != null) {
app.runInUIThread(new Runnable() {
public void run() {
resultMatcher.publish(res);
}
});
}
return res;
return new GeocodingUtilities().reverseGeocodingSearch(ctx, lat, lon);
}
}

View file

@ -19,11 +19,11 @@ import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import net.osmand.GeoidAltitudeCorrection;
import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.access.NavigationInfo;
import net.osmand.binary.GeocodingUtilities.GeocodingResult;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPoint;
@ -848,6 +848,10 @@ public class OsmAndLocationProvider implements SensorEventListener {
public void getRouteSegment(net.osmand.Location loc, ResultMatcher<RouteDataObject> result) {
currentPositionHelper.getRouteSegment(loc, result);
}
public void getGeocodingResult(net.osmand.Location loc, ResultMatcher<GeocodingResult> result) {
currentPositionHelper.getGeocodingResult(loc, result);
}
public net.osmand.Location getLastKnownLocation() {
return location;

View file

@ -3,6 +3,7 @@ package net.osmand.plus.mapcontextmenu;
import android.graphics.drawable.Drawable;
import net.osmand.Location;
import net.osmand.ResultMatcher;
import net.osmand.binary.GeocodingUtilities.GeocodingResult;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
@ -134,24 +135,37 @@ public abstract class MenuTitleController {
ll.setLatitude(getLatLon().getLatitude());
ll.setLongitude(getLatLon().getLongitude());
getMapActivity().getMyApplication().getLocationProvider()
.getRouteSegment(ll, new ResultMatcher<RouteDataObject>() {
.getGeocodingResult(ll, new ResultMatcher<GeocodingResult>() {
@Override
public boolean publish(RouteDataObject object) {
public boolean publish(GeocodingResult object) {
if (object != null) {
OsmandSettings settings = getMapActivity().getMyApplication().getSettings();
String streetName = object.getName(settings.MAP_PREFERRED_LOCALE.get());
String ref = object.getRef();
if(Algorithms.isEmpty(streetName)) {
streetName = "";
}
if(!Algorithms.isEmpty(ref)) {
if(!Algorithms.isEmpty(streetName)) {
streetName += ", ";
String lang = settings.MAP_PREFERRED_LOCALE.get();
String geocodingResult = "";
if(object.building != null) {
geocodingResult = object.street.getName(lang) + ", " + object.building.getName(lang)+ ", " + object.city.getName(lang);
} else if(object.street != null) {
geocodingResult = object.street.getName(lang) + ", " + object.city.getName(lang);
} else if(object.city != null) {
geocodingResult = object.city.getName(lang);
} else if(object.point != null) {
RouteDataObject rd = object.point.getRoad();
String sname = rd.getName(lang);
if(Algorithms.isEmpty(sname)) {
sname = "";
}
streetName += ref;
String ref = rd.getRef();
if(!Algorithms.isEmpty(ref)) {
if(!Algorithms.isEmpty(sname)) {
sname += ", ";
}
sname += ref;
}
geocodingResult = sname;
}
streetStr = streetName;
streetStr = geocodingResult;
if (!Algorithms.isEmpty(streetStr)) {
MenuController menuController = getMenuController();
if (menuController == null || menuController.displayStreetNameInTitle()) {

View file

@ -5,6 +5,8 @@ import java.util.Comparator;
import java.util.List;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.GeocodingUtilities.GeocodingResult;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.LatLon;
@ -56,6 +58,7 @@ public interface RegionAddressRepository {
public List<MapObject> searchMapObjectsByName(String name, ResultMatcher<MapObject> resultMatcher);
public BinaryMapIndexReader getFile();
public static class MapObjectNameDistanceComparator implements Comparator<MapObject> {
@ -87,4 +90,6 @@ public interface RegionAddressRepository {
}
}
public List<GeocodingResult> justifyReverseGeocodingSearch(GeocodingResult r, double minBuildingDistance);
}

View file

@ -4,6 +4,7 @@ package net.osmand.plus.resources;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -18,6 +19,8 @@ import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapAddressReaderAdapter;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.binary.GeocodingUtilities;
import net.osmand.binary.GeocodingUtilities.GeocodingResult;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.LatLon;
@ -59,6 +62,21 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
public void close(){
this.file = null;
}
@Override
public BinaryMapIndexReader getFile() {
return file;
}
@Override
public synchronized List<GeocodingResult> justifyReverseGeocodingSearch(GeocodingResult r, double minBuildingDistance) {
try {
return new GeocodingUtilities().justifyReverseGeocodingSearch(r, file, minBuildingDistance);
} catch(IOException e) {
log.error("Disk operation failed", e); //$NON-NLS-1$
}
return Collections.emptyList();
}
@Override