diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java index 08a2b4a76a..b0e529f228 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java @@ -1,31 +1,48 @@ package net.osmand.binary; +import gnu.trove.iterator.TIntIterator; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.TIntObjectMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.set.hash.TIntHashSet; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.RandomAccessFile; +import java.io.Reader; +import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + import net.osmand.Collator; import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher.StringMatcherMode; +import net.osmand.Location; import net.osmand.OsmAndCollator; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.StringMatcher; import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion; import net.osmand.binary.BinaryMapAddressReaderAdapter.CitiesBlock; +import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter; +import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.binary.BinaryMapPoiReaderAdapter.PoiRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion; @@ -43,10 +60,16 @@ import net.osmand.data.MapObject; import net.osmand.data.Street; import net.osmand.data.TransportRoute; import net.osmand.data.TransportStop; +import net.osmand.osm.edit.Way; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import com.google.protobuf.CodedInputStream; import com.google.protobuf.WireFormat; @@ -1317,6 +1340,8 @@ public class BinaryMapIndexReader { return buildSearchRequest(sleft, sright, stop, sbottom, zoom, searchFilter, null); } + + public static SearchRequest buildSearchRequest(int sleft, int sright, int stop, int sbottom, int zoom, SearchFilter searchFilter, ResultMatcher resultMatcher){ SearchRequest request = new SearchRequest(); @@ -1345,6 +1370,54 @@ public class BinaryMapIndexReader { return request; } + public static SearchRequest buildSearchPoiRequest(List route, double radius, + SearchPoiTypeFilter poiTypeFilter, ResultMatcher resultMatcher) { + SearchRequest request = new SearchRequest(); + float coeff = (float) (radius / MapUtils.getTileDistanceWidth(SearchRequest.ZOOM_TO_SEARCH_POI)); + TIntObjectHashMap> zooms = new TIntObjectHashMap>(); + for(int i = 1; i < route.size(); i++) { + Location cr = route.get(i); + Location pr = route.get(i - 1); + double tx = MapUtils.getTileNumberX(SearchRequest.ZOOM_TO_SEARCH_POI, cr.getLongitude()); + double ty = MapUtils.getTileNumberY(SearchRequest.ZOOM_TO_SEARCH_POI, cr.getLatitude()); + double px = MapUtils.getTileNumberX(SearchRequest.ZOOM_TO_SEARCH_POI, pr.getLongitude()); + double py = MapUtils.getTileNumberY(SearchRequest.ZOOM_TO_SEARCH_POI, pr.getLatitude()); + double topLeftX = Math.min(tx, px) - coeff; + double topLeftY = Math.min(ty, py) - coeff; + double bottomRightX = Math.max(tx, px) + coeff; + double bottomRightY = Math.max(ty, py) + coeff; + for(int x = (int) topLeftX; x <= bottomRightX; x++) { + for(int y = (int) topLeftY; y <= bottomRightY; y++) { + int hash = (x << SearchRequest.ZOOM_TO_SEARCH_POI) + y; + if(!zooms.containsKey(hash)) { + zooms.put(hash, new LinkedList()); + } + List ll = zooms.get(hash); + ll.add(pr); + ll.add(cr); + } + } + + } + int sleft = 0, sright = Integer.MAX_VALUE, stop = 0, sbottom = Integer.MAX_VALUE; + for(int vl : zooms.keys()) { + int x = (vl >> SearchRequest.ZOOM_TO_SEARCH_POI) << (31 - SearchRequest.ZOOM_TO_SEARCH_POI); + int y = (vl & ((1 << SearchRequest.ZOOM_TO_SEARCH_POI) -1)) << (31 - SearchRequest.ZOOM_TO_SEARCH_POI); + sleft = Math.min(x, sleft); + stop = Math.min(y, stop); + sbottom = Math.max(y, sbottom); + sright = Math.max(x, sright); + } + request.radius = radius; + request.left = sleft; + request.right = sright; + request.top = stop; + request.bottom = sbottom; + request.tiles = zooms; + request.poiTypeFilter = poiTypeFilter; + request.resultMatcher = resultMatcher; + return request; + } public static SearchRequest buildSearchPoiRequest(int sleft, int sright, int stop, int sbottom, int zoom, SearchPoiTypeFilter poiTypeFilter, ResultMatcher matcher){ @@ -1426,6 +1499,7 @@ public class BinaryMapIndexReader { } public static class SearchRequest { + public final static int ZOOM_TO_SEARCH_POI = 16; private List searchResults = new ArrayList(); private boolean land = false; private boolean ocean = false; @@ -1443,6 +1517,11 @@ public class BinaryMapIndexReader { int zoom = 15; int limit = -1; + + // search on the path + // stores tile of 16 index and pairs (even length always) of points intersecting tile + TIntObjectHashMap> tiles = null; + double radius = -1; String nameQuery = null; @@ -1469,6 +1548,12 @@ public class BinaryMapIndexReader { protected SearchRequest(){ } + public int getTileHashOnPath(double lat, double lon) { + int x = (int) MapUtils.getTileNumberX(SearchRequest.ZOOM_TO_SEARCH_POI, lon); + int y = (int) MapUtils.getTileNumberY(SearchRequest.ZOOM_TO_SEARCH_POI, lat); + return (x << SearchRequest.ZOOM_TO_SEARCH_POI) | y; + } + public boolean publish(T obj){ if(resultMatcher == null || resultMatcher.publish(obj)){ @@ -1769,7 +1854,7 @@ public class BinaryMapIndexReader { } - private static boolean testMapSearch = true; + private static boolean testMapSearch = false; private static boolean testAddressSearch = false; private static boolean testPoiSearch = false; private static boolean testTransportSearch = false; @@ -1805,17 +1890,120 @@ public class BinaryMapIndexReader { PoiRegion poiRegion = reader.getPoiIndexes().get(0); testPoiSearch(reader, poiRegion); testPoiSearchByName(reader); + testSearchOnthePath(reader); } println("MEMORY " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); //$NON-NLS-1$ println("Time " + (System.currentTimeMillis() - time)); //$NON-NLS-1$ } + private static void testSearchOnthePath(BinaryMapIndexReader reader) throws IOException { + float radius = 1000; + long now = System.currentTimeMillis(); + println("Searching poi on the path..."); + final List locations = readGPX(new File( + "")); + SearchRequest req = buildSearchPoiRequest(locations, radius, new SearchPoiTypeFilter() { + @Override + public boolean accept(AmenityType type, String subcategory) { + if (type == AmenityType.SHOP && subcategory.contains("super")) { + return true; + } + return false; + } + + }, null); + req.zoom = -1; + List results = reader.searchPoi(req); + int k = 0; + println("Search done in " + (System.currentTimeMillis() - now) + " ms "); + now = System.currentTimeMillis(); + + for (Amenity a : results) { + final float dds = dist(a.getLocation(), locations); + if (dds <= radius) { + println("+ " + a.getType() + " " + a.getSubType() + " Dist " + dds + " (=" + (float)a.getDeviateDistance() + ") " + a.getName() + " " + a.getLocation()); + k++; + } else { + println(a.getType() + " " + a.getSubType() + " Dist " + dds + " " + a.getName() + " " + a.getLocation()); + } + } + println("Filtered in " + (System.currentTimeMillis() - now) + "ms " + k + " of " + results.size()); + } + + private static float dist(LatLon l, List locations) { + float dist = Float.POSITIVE_INFINITY; + for(int i = 1; i < locations.size(); i++){ + dist = Math.min(dist,(float) MapUtils.getOrthogonalDistance(l.getLatitude(), l.getLongitude(), + locations.get(i-1).getLatitude(), locations.get(i-1).getLongitude(), + locations.get(i).getLatitude(), locations.get(i).getLongitude())); + } + return dist; + } + + private static Reader getUTF8Reader(InputStream f) throws IOException { + BufferedInputStream bis = new BufferedInputStream(f); + assert bis.markSupported(); + bis.mark(3); + boolean reset = true; + byte[] t = new byte[3]; + bis.read(t); + if (t[0] == ((byte) 0xef) && t[1] == ((byte) 0xbb) && t[2] == ((byte) 0xbf)) { + reset = false; + } + if (reset) { + bis.reset(); + } + return new InputStreamReader(bis, "UTF-8"); + } + + private static List readGPX(File f) { + List res = new ArrayList(); + try { + StringBuilder content = new StringBuilder(); + BufferedReader reader = new BufferedReader(getUTF8Reader(new FileInputStream(f))); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dom = factory.newDocumentBuilder(); +// { +// String s = null; +// boolean fist = true; +// while ((s = reader.readLine()) != null) { +// if (fist) { +// fist = false; +// } +// content.append(s).append("\n"); +// } +// } +// Document doc = dom.parse(new InputSource(new StringReader(content.toString()))); + Document doc = dom.parse(new InputSource(reader)); + NodeList list = doc.getElementsByTagName("trkpt"); + Way w = new Way(-1); + for (int i = 0; i < list.getLength(); i++) { + Element item = (Element) list.item(i); + try { + double lon = Double.parseDouble(item.getAttribute("lon")); + double lat = Double.parseDouble(item.getAttribute("lat")); + final Location o = new Location(""); + o.setLatitude(lat); + o.setLongitude(lon); + res.add(o); + } catch (NumberFormatException e) { + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } catch (ParserConfigurationException e) { + throw new RuntimeException(e); + } catch (SAXException e) { + throw new RuntimeException(e); + } + return res; + } + private static void testPoiSearchByName(BinaryMapIndexReader reader) throws IOException { println("Searching by name..."); - int tileZ = 31 - 14; - SearchRequest req = buildSearchPoiRequest(sleft/2+sright/2, stop/2+sbottom/2, "kol", - sleft - 1< req = buildSearchPoiRequest(0, 0, "roch", + 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, null); reader.searchPoiByName(req); for (Amenity a : req.getSearchResults()) { println(a.getType() + " " + a.getSubType() + " " + a.getName() + " " + a.getLocation()); @@ -2107,5 +2295,7 @@ public class BinaryMapIndexReader { routeAdapter.initRouteRegion(routeReg); } } + + } \ No newline at end of file diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java b/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java index 24b6b75e1b..72f4eea566 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java @@ -15,11 +15,13 @@ import java.util.List; import net.osmand.Collator; import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher.StringMatcherMode; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.binary.OsmandOdb.OsmAndPoiNameIndex.OsmAndPoiNameIndexData; import net.osmand.data.Amenity; import net.osmand.data.AmenityType; +import net.osmand.data.LatLon; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import net.sf.junidecode.Junidecode; @@ -588,6 +590,17 @@ public class BinaryMapPoiReaderAdapter { } } + private float dist(LatLon l, List locations) { + float dist = Float.POSITIVE_INFINITY; + // Special iterations because points stored by pairs! + for (int i = 1; i < locations.size(); i += 2) { + dist = Math.min(dist, (float) MapUtils.getOrthogonalDistance( + l.getLatitude(), l.getLongitude(), + locations.get(i - 1).getLatitude(), locations.get(i - 1).getLongitude(), + locations.get(i).getLatitude(), locations.get(i).getLongitude())); + } + return dist; + } private Amenity readPoiPoint(int left31, int right31, int top31, int bottom31, int px, int py, int zoom, SearchRequest req, PoiRegion region, boolean checkBounds) throws IOException { Amenity am = null; @@ -609,6 +622,19 @@ public class BinaryMapPoiReaderAdapter { am.setEnName(Junidecode.unidecode(am.getName())); } req.numberOfAcceptedObjects++; + if (req.radius > 0) { + LatLon loc = am.getLocation(); + List locs = req.tiles.get(req.getTileHashOnPath(loc.getLatitude(), loc.getLongitude())); + if (locs == null) { + return null; + } + float d = dist(am.getLocation(), locs); + if (d > req.radius) { + return null; + } else { + am.setDeviateDistance(d); + } + } return am; case OsmandOdb.OsmAndPoiBoxDataAtom.DX_FIELD_NUMBER : x = (codedIS.readSInt32() + (px << (24 - zoom))) << 7; @@ -793,16 +819,16 @@ public class BinaryMapPoiReaderAdapter { case OsmandOdb.OsmAndPoiBox.SUBBOXES_FIELD_NUMBER: { int x = dx + (px << (zoom - pzoom)); int y = dy + (py << (zoom - pzoom)); - if(checkBox){ + if (checkBox) { int xL = x << (31 - zoom); int xR = ((x + 1) << (31 - zoom)) - 1; int yT = y << (31 - zoom); int yB = ((y + 1) << (31 - zoom)) - 1; // check intersection - if(left31 > xR || xL > right31 || bottom31 < yT || yB < top31){ + if (left31 > xR || xL > right31 || bottom31 < yT || yB < top31) { codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); return false; - } + } req.numberOfAcceptedSubtrees++; checkBox = false; } @@ -824,10 +850,20 @@ public class BinaryMapPoiReaderAdapter { int x = dx + (px << (zoom - pzoom)); int y = dy + (py << (zoom - pzoom)); long l = ((((x << zoom) | y) << 5) | zoom); - offsetsMap.put(readInt(), l); - if(skipTiles != null && zoom >= zoomToSkip){ - long val = ((((long) x) >> (zoom - zoomToSkip)) << zoomToSkip) | (((long) y) >> (zoom - zoomToSkip)); - skipTiles.add(val); + boolean read = true; + if(req.tiles != null) { + int zx = x << (SearchRequest.ZOOM_TO_SEARCH_POI - zoom); + int zy = y << (SearchRequest.ZOOM_TO_SEARCH_POI - zoom); + read = req.tiles.contains((zx << SearchRequest.ZOOM_TO_SEARCH_POI) + zy); + } + int offset = readInt(); + if (read) { + offsetsMap.put(offset, l); + if (skipTiles != null && zoom >= zoomToSkip) { + long val = ((((long) x) >> (zoom - zoomToSkip)) << zoomToSkip) + | (((long) y) >> (zoom - zoomToSkip)); + skipTiles.add(val); + } } } break; default: diff --git a/OsmAnd-java/src/net/osmand/data/Amenity.java b/OsmAnd-java/src/net/osmand/data/Amenity.java index 98c56d6070..fc34c34d61 100644 --- a/OsmAnd-java/src/net/osmand/data/Amenity.java +++ b/OsmAnd-java/src/net/osmand/data/Amenity.java @@ -18,6 +18,7 @@ public class Amenity extends MapObject { // duplicate for fast access private String openingHours; private Map additionalInfo; + private double deviateDistance; // for search on path public Amenity(){ } @@ -62,6 +63,13 @@ public class Amenity extends MapObject { openingHours = additionalInfo.get(OPENING_HOURS); } + public double getDeviateDistance() { + return deviateDistance; + } + + public void setDeviateDistance(double deviateDistance) { + this.deviateDistance = deviateDistance; + } public void setAdditionalInfo(String tag, String value) { if(this.additionalInfo == null){ diff --git a/OsmAnd-java/src/net/osmand/util/MapUtils.java b/OsmAnd-java/src/net/osmand/util/MapUtils.java index 098c7e6545..26539d57d1 100644 --- a/OsmAnd-java/src/net/osmand/util/MapUtils.java +++ b/OsmAnd-java/src/net/osmand/util/MapUtils.java @@ -220,6 +220,12 @@ public class MapUtils { } + public static double getTileDistanceWidth(float zoom) { + LatLon ll = new LatLon(30, MapUtils.getLongitudeFromTile(zoom, 0)); + LatLon ll2 = new LatLon(30, MapUtils.getLongitudeFromTile(zoom, 1)); + return getDistance(ll, ll2) ; + } + public static double getLongitudeFromTile(float zoom, double x) { return x / getPowZoom(zoom) * 360.0 - 180.0; } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java b/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java index e019245a45..a7eeb5b5b2 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java @@ -39,6 +39,7 @@ public class SettingsMonitoringActivity extends SettingsBaseActivity { @Override public void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + requestWindowFeature(Window.FEATURE_PROGRESS); super.onCreate(savedInstanceState); setSupportProgressBarIndeterminateVisibility(false); getSupportActionBar().setTitle(R.string.monitoring_settings); diff --git a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java index 439e498bc9..c8ea50691b 100644 --- a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java +++ b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java @@ -2,6 +2,7 @@ package net.osmand.plus.resources; import java.util.List; +import net.osmand.Location; import net.osmand.ResultMatcher; import net.osmand.data.Amenity; import net.osmand.plus.PoiFilter; @@ -20,5 +21,7 @@ public interface AmenityIndexRepository { public List searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, PoiFilter filter, List amenities, ResultMatcher matcher); + public List searchAmenitiesOnThePath(List locations, double radius, PoiFilter filter, ResultMatcher matcher); + } diff --git a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java index 82a41ece38..d07dcf6c6a 100644 --- a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java @@ -6,6 +6,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapIndexReader; @@ -105,5 +106,30 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository { } return amenities; } + + @Override + public synchronized List searchAmenitiesOnThePath(List locations, double radius, final PoiFilter filter, ResultMatcher matcher) { + long now = System.currentTimeMillis(); + SearchPoiTypeFilter poiTypeFilter = new SearchPoiTypeFilter(){ + @Override + public boolean accept(AmenityType type, String subcategory) { + return filter.acceptTypeSubtype(type, subcategory); + } + }; + List result = null; + SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest(locations, radius, + poiTypeFilter, filter == null ? matcher : filter.getResultMatcher(matcher)); + try { + result = index.searchPoi(req); + } catch (IOException e) { + log.error("Error searching amenities", e); //$NON-NLS-1$ + return result; + } + if (log.isDebugEnabled() && result != null) { + log.debug(String.format("Search done in %s ms found %s.", (System.currentTimeMillis() - now), result.size())); //$NON-NLS-1$ + } + return result; + + } } diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index 36b92ae011..e4d530384f 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -1,8 +1,6 @@ package net.osmand.plus.resources; -import gnu.trove.list.array.TIntArrayList; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -23,6 +21,7 @@ import net.osmand.AndroidUtils; import net.osmand.GeoidAltitudeCorrection; import net.osmand.IProgress; import net.osmand.IndexConstants; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapIndexReader; @@ -736,7 +735,7 @@ public class ResourceManager { if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { index.searchAmenities(MapUtils.get31TileNumberY(topLatitude), MapUtils.get31TileNumberX(leftLongitude), MapUtils.get31TileNumberY(bottomLatitude), - MapUtils.get31TileNumberX(rightLongitude), -1, filter, amenities, + MapUtils.get31TileNumberX(rightLongitude), zoom, filter, amenities, new ResultMatcher() { @Override @@ -814,21 +813,18 @@ public class ResourceManager { return map; } - public void searchAmenitiesOnTheArea(TIntArrayList tiles16z, PoiFilter filter, ResultMatcher results) { - if (tiles16z.size() > 0) { - int z = 16; - int x = tiles16z.get(0) >> z; - int y = tiles16z.get(0) & ((1 << z) - 1); + public void searchAmenitiesOnThePath(List locations, double radius, PoiFilter filter, ResultMatcher matcher) { + if (locations != null && locations.size() > 0) { List repos = new ArrayList(); - double topLatitude = MapUtils.getLatitudeFromTile(z, y); - double bottomLatitude = MapUtils.getLatitudeFromTile(z, y + 1); - double leftLongitude = MapUtils.getLongitudeFromTile(z, x); - double rightLongitude = MapUtils.getLongitudeFromTile(z, x + 1); - for (int k = 1; k < tiles16z.size(); k++) { - topLatitude = Math.max(topLatitude, MapUtils.getLatitudeFromTile(z, y)); - bottomLatitude = Math.min(bottomLatitude, MapUtils.getLatitudeFromTile(z, y + 1)); - leftLongitude = Math.min(leftLongitude, MapUtils.getLongitudeFromTile(z, x)); - rightLongitude = Math.max(rightLongitude, MapUtils.getLongitudeFromTile(z, x + 1)); + double topLatitude = locations.get(0).getLatitude(); + double bottomLatitude = locations.get(0).getLatitude(); + double leftLongitude = locations.get(0).getLongitude(); + double rightLongitude = locations.get(0).getLongitude(); + for(Location l : locations) { + topLatitude = Math.max(topLatitude, l.getLatitude()); + bottomLatitude = Math.min(bottomLatitude, l.getLatitude()); + leftLongitude = Math.min(leftLongitude, l.getLongitude()); + rightLongitude = Math.max(rightLongitude, l.getLongitude()); } for (AmenityIndexRepository index : amenityRepositories) { if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { @@ -837,7 +833,7 @@ public class ResourceManager { } if (!repos.isEmpty()) { for(AmenityIndexRepository r : repos) { -// r.searchAmenities(stop, sleft, sbottom, sright, zoom, filter, amenities, matcher) + r.searchAmenitiesOnThePath(locations, radius, filter, matcher); } } }