public void loadBorderPoints() throws IOException { Iterator<Entry<RouteRegion, BinaryMapIndexReader>> it = reverseMap.entrySet().iterator(); int sleft = Math.min(startX, targetX); int sright = Math.max(startX, targetX); int stop = Math.min(startY, targetY); int sbottom = Math.max(startY, targetY); // one tile of 12th zoom around (?) int zoomAround = 10; int distAround = 1 << (31 - zoomAround); leftBorderBoundary = sleft - distAround; rightBorderBoundary = sright + distAround; SearchRequest<RouteDataBorderLinePoint> req = BinaryMapIndexReader.buildSearchRouteBorderRequest(sleft, sright, stop, sbottom); while (it.hasNext()) { Entry<RouteRegion, BinaryMapIndexReader> entry = it.next(); entry.getValue().searchBorderPoints(req, entry.getKey()); } TIntObjectHashMap<RouteDataBorderLine> lines = new TIntObjectHashMap<RoutingContext.RouteDataBorderLine>(); for (RouteDataBorderLinePoint p : req.getSearchResults()) { if (config.router.acceptLine(p) && p.x > leftBorderBoundary && p.x < rightBorderBoundary) { if (!lines.containsKey(p.y)) { RouteDataBorderLine line = new RouteDataBorderLine(p.y); lines.put(p.y, line); RouteDataBorderLinePoint lft = new RouteDataBorderLinePoint(p.region); lft.y = p.y; lft.id = Long.MIN_VALUE; lft.x = leftBorderBoundary; line.borderPoints.add(lft); RouteDataBorderLinePoint rht = new RouteDataBorderLinePoint(p.region); rht.y = p.y; rht.id = Long.MIN_VALUE; rht.x = rightBorderBoundary; line.borderPoints.add(rht); } lines.get(p.y).borderPoints.add(p); } } borderLines = lines.values(new RouteDataBorderLine[lines.size()]); Arrays.sort(borderLines); borderLineCoordinates = new int[borderLines.length]; for (int i = 0; i < borderLineCoordinates.length; i++) { borderLineCoordinates[i] = borderLines[i].borderLine; // FIXME borders approach // not less then 14th zoom if (i > 0 && borderLineCoordinates[i - 1] >> 17 == borderLineCoordinates[i] >> 17) { throw new IllegalStateException(); } System.out.println( "Line " + (borderLineCoordinates[i] >> 17) + " points " + borderLines[i].borderPoints.size() /* + " " +borderLines[i].borderPoints*/); } updateDistanceForBorderPoints(startX, startY, true); updateDistanceForBorderPoints(targetX, targetY, false); }
private void readBorderLines( SearchRequest<RouteDataBorderLinePoint> req, TIntArrayList blocksToRead) throws IOException { while (true) { int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: return; case RouteBorderBox.BORDERLINES_FIELD_NUMBER: { int fp = codedIS.getTotalBytesRead(); int length = codedIS.readRawVarint32(); int old = codedIS.pushLimit(length); RouteBorderLine ln = readBorderLine(); if (ln.hasTox() && req.intersects(ln.getX(), ln.getY(), ln.getTox(), ln.getY())) { blocksToRead.add(ln.getShiftToPointsBlock() + fp); // FIXME borders approach // } else if(ln.hasToy() && req.intersects(ln.getX(), ln.getY(), ln.getX(), // ln.getToy())) { // blocksToRead.add(ln.getShiftToPointsBlock() + fp); } codedIS.popLimit(old); break; } case RouteBorderBox.BLOCKS_FIELD_NUMBER: return; default: skipUnknownField(t); break; } } }
public void initRouteTypesIfNeeded(SearchRequest<RouteDataObject> req, List<RouteSubregion> list) throws IOException { for (RouteSubregion rs : list) { if (req.intersects(rs.left, rs.top, rs.right, rs.bottom)) { initRouteRegion(rs.routeReg); } } }
public List<RouteSubregion> loadInteresectedPoints( SearchRequest<RouteDataObject> req, List<RouteSubregion> list, List<RouteSubregion> toLoad) throws IOException { for (RouteSubregion rs : list) { if (req.intersects(rs.left, rs.top, rs.right, rs.bottom)) { if (rs.subregions == null) { codedIS.seek(rs.filePointer); int old = codedIS.pushLimit(rs.length); readRouteTree( rs, null, req.contains(rs.left, rs.top, rs.right, rs.bottom) ? -1 : 1, false); codedIS.popLimit(old); } searchRouteRegionTree(req, rs.subregions, toLoad); if (rs.shiftToData != 0) { toLoad.add(rs); } } } return toLoad; }
private void readBorderLinePoints(SearchRequest<RouteDataBorderLinePoint> req, RouteRegion r) throws IOException { int x = 0; int y = 0; long id = 0; while (true) { int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: return; case RouteBorderPointsBlock.X_FIELD_NUMBER: { x = codedIS.readInt32(); break; } case RouteBorderPointsBlock.Y_FIELD_NUMBER: { y = codedIS.readInt32(); break; } case RouteBorderPointsBlock.BASEID_FIELD_NUMBER: { id = codedIS.readInt64(); break; } case RouteBorderPointsBlock.POINTS_FIELD_NUMBER: int len = codedIS.readRawVarint32(); int oldLimit = codedIS.pushLimit(len); RouteDataBorderLinePoint p = readBorderLinePoint(new RouteDataBorderLinePoint(r), x, y, id); codedIS.popLimit(oldLimit); x = p.x; y = p.y; id = p.id; req.publish(p); break; default: skipUnknownField(t); break; } } }
public List<RouteDataBorderLinePoint> searchBorderPoints( SearchRequest<RouteDataBorderLinePoint> req, RouteRegion r) throws IOException { if (r.borderBoxPointer != 0) { codedIS.seek(r.borderBoxPointer); int old = codedIS.pushLimit(r.borderBoxLength); TIntArrayList blocksToRead = new TIntArrayList(); readBorderLines(req, blocksToRead); blocksToRead.sort(); for (int j = 0; j < blocksToRead.size(); j++) { codedIS.seek(blocksToRead.get(j)); int len = codedIS.readRawVarint32(); int oldLimit = codedIS.pushLimit(len); readBorderLinePoints(req, r); codedIS.popLimit(oldLimit); } codedIS.popLimit(old); } return req.getSearchResults(); }
protected void searchTransportTreeBounds( int pleft, int pright, int ptop, int pbottom, SearchRequest<TransportStop> req) throws IOException { int init = 0; int lastIndexResult = -1; int cright = 0; int cleft = 0; int ctop = 0; int cbottom = 0; req.numberOfReadSubtrees++; while (true) { if (req.isInterrupted()) { return; } int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); if (init == 0xf) { // coordinates are init init = 0; if (cright < req.left || cleft > req.right || ctop > req.bottom || cbottom < req.top) { return; } else { req.numberOfAcceptedSubtrees++; } } switch (tag) { case 0: return; case OsmandOdb.TransportStopsTree.BOTTOM_FIELD_NUMBER: cbottom = codedIS.readSInt32() + pbottom; init |= 1; break; case OsmandOdb.TransportStopsTree.LEFT_FIELD_NUMBER: cleft = codedIS.readSInt32() + pleft; init |= 2; break; case OsmandOdb.TransportStopsTree.RIGHT_FIELD_NUMBER: cright = codedIS.readSInt32() + pright; init |= 4; break; case OsmandOdb.TransportStopsTree.TOP_FIELD_NUMBER: ctop = codedIS.readSInt32() + ptop; init |= 8; break; case OsmandOdb.TransportStopsTree.LEAFS_FIELD_NUMBER: int stopOffset = codedIS.getTotalBytesRead(); int length = codedIS.readRawVarint32(); int oldLimit = codedIS.pushLimit(length); if (lastIndexResult == -1) { lastIndexResult = req.searchResults.size(); } req.numberOfVisitedObjects++; TransportStop transportStop = readTransportStop(stopOffset, cleft, cright, ctop, cbottom, req); if (transportStop != null) { req.searchResults.add(transportStop); } codedIS.popLimit(oldLimit); break; case OsmandOdb.TransportStopsTree.SUBTREES_FIELD_NUMBER: // left, ... already initialized length = readInt(); int filePointer = codedIS.getTotalBytesRead(); if (req.limit == -1 || req.limit >= req.searchResults.size()) { oldLimit = codedIS.pushLimit(length); searchTransportTreeBounds(cleft, cright, ctop, cbottom, req); codedIS.popLimit(oldLimit); } codedIS.seek(filePointer + length); if (lastIndexResult >= 0) { throw new IllegalStateException(); } break; case OsmandOdb.TransportStopsTree.BASEID_FIELD_NUMBER: long baseId = codedIS.readUInt64(); if (lastIndexResult != -1) { for (int i = lastIndexResult; i < req.searchResults.size(); i++) { TransportStop rs = req.searchResults.get(i); rs.setId(rs.getId() + baseId); } } break; default: skipUnknownField(t); break; } } }
public void loadRoutes(final RoutingContext ctx, int tileX, int tileY) throws IOException { int tileC = (tileX << ctx.getZoomToLoadTileWithRoads()) + tileY; if (ctx.loadedTiles.contains(tileC)) { return; } long now = System.nanoTime(); int zoomToLoad = 31 - ctx.getZoomToLoadTileWithRoads(); SearchFilter searchFilter = new BinaryMapIndexReader.SearchFilter() { @Override public boolean accept(TIntArrayList types, MapIndex index) { for (int j = 0; j < types.size(); j++) { int wholeType = types.get(j); TagValuePair pair = index.decodeType(wholeType); if (pair != null) { int t = wholeType & 3; if (t == MapRenderingTypes.POINT_TYPE) { if (ctx.getRouter().acceptPoint(pair)) { return true; } } else if (t == MapRenderingTypes.POLYLINE_TYPE) { if (ctx.getRouter().acceptLine(pair)) { return true; } } } } return false; } }; SearchRequest<BinaryMapDataObject> request = BinaryMapIndexReader.buildSearchRequest( tileX << zoomToLoad, (tileX + 1) << zoomToLoad, tileY << zoomToLoad, (tileY + 1) << zoomToLoad, 15, searchFilter); for (BinaryMapIndexReader r : map) { r.searchMapIndex(request); for (BinaryMapDataObject o : request.getSearchResults()) { BinaryMapDataObject old = ctx.idObjects.get(o.getId()); // sometimes way are presented only partially in one index if (old != null && old.getPointsLength() >= o.getPointsLength()) { continue; } ctx.idObjects.put(o.getId(), o); for (int j = 0; j < o.getPointsLength(); j++) { long l = (((long) o.getPoint31XTile(j)) << 31) + (long) o.getPoint31YTile(j); RouteSegment segment = new RouteSegment(); segment.road = o; segment.segmentEnd = segment.segmentStart = j; if (ctx.routes.get(l) != null) { segment.next = ctx.routes.get(l); } ctx.routes.put(l, segment); } } ctx.loadedTiles.add(tileC); ctx.timeToLoad += (System.nanoTime() - now); } }
public List<GeocodingResult> justifyReverseGeocodingSearch( final GeocodingResult road, BinaryMapIndexReader reader, double knownMinBuildingDistance, final ResultMatcher<GeocodingResult> result) throws IOException { // test address index search final List<GeocodingResult> streetsList = new ArrayList<GeocodingResult>(); final List<String> streetNamePacked = prepareStreetName(road.streetName); if (streetNamePacked.size() > 0) { log.info("Search street by name " + road.streetName + " " + streetNamePacked); String mainWord = ""; for (int i = 0; i < streetNamePacked.size(); i++) { String s = streetNamePacked.get(i); if (!getSuffixesSet().contains(s) && s.length() > mainWord.length()) { mainWord = s; } } if (Algorithms.isEmpty(mainWord)) { mainWord = streetNamePacked.get(0); } SearchRequest<MapObject> req = BinaryMapIndexReader.buildAddressByNameRequest( new ResultMatcher<MapObject>() { @Override public boolean publish(MapObject object) { if (object instanceof Street && prepareStreetName(object.getName()).equals(streetNamePacked)) { double d = MapUtils.getDistance( object.getLocation(), road.searchPoint.getLatitude(), road.searchPoint.getLongitude()); // double check to suport old format if (d < DISTANCE_STREET_NAME_PROXIMITY_BY_NAME) { GeocodingResult rs = new GeocodingResult(road); rs.street = (Street) object; // set connection point to sort rs.connectionPoint = rs.street.getLocation(); rs.city = rs.street.getCity(); streetsList.add(rs); return true; } return false; } return false; } @Override public boolean isCancelled() { return result != null && result.isCancelled(); } }, mainWord, StringMatcherMode.CHECK_EQUALS_FROM_SPACE); req.setBBoxRadius( road.getLocation().getLatitude(), road.getLocation().getLongitude(), DISTANCE_STREET_NAME_PROXIMITY_BY_NAME); reader.searchAddressDataByName(req); } final List<GeocodingResult> res = new ArrayList<GeocodingResult>(); if (streetsList.size() == 0) { res.add(road); } else { Collections.sort(streetsList, DISTANCE_COMPARATOR); double streetDistance = 0; for (GeocodingResult street : streetsList) { if (streetDistance == 0) { streetDistance = street.getDistance(); } else if (street.getDistance() > streetDistance + DISTANCE_STREET_FROM_CLOSEST_WITH_SAME_NAME) { continue; } street.connectionPoint = road.connectionPoint; final List<GeocodingResult> streetBuildings = loadStreetBuildings(road, reader, street); Collections.sort(streetBuildings, DISTANCE_COMPARATOR); if (streetBuildings.size() > 0) { Iterator<GeocodingResult> it = streetBuildings.iterator(); if (knownMinBuildingDistance == 0) { GeocodingResult firstBld = it.next(); knownMinBuildingDistance = firstBld.getDistance(); res.add(firstBld); } while (it.hasNext()) { GeocodingResult nextBld = it.next(); if (nextBld.getDistance() > knownMinBuildingDistance * THRESHOLD_MULTIPLIER_SKIP_BUILDINGS_AFTER) { break; } res.add(nextBld); } } res.add(street); } } Collections.sort(res, DISTANCE_COMPARATOR); return res; }