protected void updateDistanceForBorderPoints(int sX, int sy, boolean distanceToStart) { boolean plus = borderLines.length > 0 && sy < borderLines[0].borderLine; if (borderLines.length > 0 && !plus && sy < borderLines[borderLines.length - 1].borderLine) { throw new IllegalStateException(); } // calculate min distance to start for (int i = 0; i < borderLines.length; i++) { int ind = plus ? i : borderLines.length - i - 1; for (RouteDataBorderLinePoint ps : borderLines[ind].borderPoints) { float res = (float) Math.sqrt(MapUtils.squareDist31TileMetric(sX, sy, ps.x, ps.y)); if (i > 0) { int prevInd = plus ? i - 1 : borderLines.length - i; double minDist = 0; for (RouteDataBorderLinePoint prevs : borderLines[prevInd].borderPoints) { double d = Math.sqrt(MapUtils.squareDist31TileMetric(prevs.x, prevs.y, ps.x, ps.y)) + (distanceToStart ? prevs.distanceToStartPoint : prevs.distanceToEndPoint); if (minDist == 0 || d < minDist) { minDist = d; } } if (minDist > 0) { // System.out.println("Border line " + i + " exp="+res + " min="+ minDist); res = (float) minDist; } } if (distanceToStart) { ps.distanceToStartPoint = res; } else { ps.distanceToEndPoint = res; } } } }
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); }