public List<OrderedCanvasIdPair> getSortedNeighborPairs() throws IOException, InterruptedException { LOG.info("getSortedNeighborPairs: entry"); final List<Double> zValues = renderDataClient.getStackZValues(parameters.stack, parameters.minZ, parameters.maxZ); final Map<Double, TileBoundsRTree> zToTreeMap = buildRTrees(zValues); final Set<OrderedCanvasIdPair> existingPairs = getExistingPairs(); final Set<OrderedCanvasIdPair> neighborPairs = new TreeSet<>(); Double z; Double neighborZ; TileBoundsRTree currentZTree; List<TileBoundsRTree> neighborTreeList; Set<OrderedCanvasIdPair> currentNeighborPairs; for (int zIndex = 0; zIndex < zValues.size(); zIndex++) { z = zValues.get(zIndex); currentZTree = zToTreeMap.get(z); neighborTreeList = new ArrayList<>(); final double maxNeighborZ = Math.min(parameters.maxZ, z + parameters.zNeighborDistance); for (int neighborZIndex = zIndex + 1; neighborZIndex < zValues.size(); neighborZIndex++) { neighborZ = zValues.get(neighborZIndex); if (neighborZ > maxNeighborZ) { break; } neighborTreeList.add(zToTreeMap.get(neighborZ)); } currentNeighborPairs = currentZTree.getCircleNeighbors( neighborTreeList, parameters.xyNeighborFactor, parameters.excludeCornerNeighbors, parameters.excludeSameLayerNeighbors, parameters.excludeSameSectionNeighbors); if (existingPairs.size() > 0) { final int beforeSize = currentNeighborPairs.size(); currentNeighborPairs.removeAll(existingPairs); final int afterSize = currentNeighborPairs.size(); LOG.info("removed {} existing pairs for z {}", (beforeSize - afterSize), z); } neighborPairs.addAll(currentNeighborPairs); } LOG.info("getSortedNeighborPairs: exit, returning {} pairs", neighborPairs.size()); return new ArrayList<>(neighborPairs); }
@Nonnull private Map<Double, TileBoundsRTree> buildRTrees(final List<Double> zValues) throws IOException { final Map<Double, TileBoundsRTree> zToTreeMap = new LinkedHashMap<>(); long totalTileCount = 0; long filteredTileCount = 0; for (final Double z : zValues) { List<TileBounds> tileBoundsList = renderDataClient.getTileBounds(parameters.stack, z); TileBoundsRTree tree = new TileBoundsRTree(z, tileBoundsList); totalTileCount += tileBoundsList.size(); if (filterTilesWithBox) { final int unfilteredCount = tileBoundsList.size(); tileBoundsList = tree.findTilesInBox( parameters.minX, parameters.minY, parameters.maxX, parameters.maxY); if (unfilteredCount > tileBoundsList.size()) { LOG.info( "buildRTrees: removed {} tiles outside of bounding box", (unfilteredCount - tileBoundsList.size())); tree = new TileBoundsRTree(z, tileBoundsList); } } if (parameters.excludeCompletelyObscuredTiles) { final int unfilteredCount = tileBoundsList.size(); tileBoundsList = tree.findVisibleTiles(); if (unfilteredCount > tileBoundsList.size()) { LOG.info( "buildRTrees: removed {} completely obscured tiles", (unfilteredCount - tileBoundsList.size())); tree = new TileBoundsRTree(z, tileBoundsList); } } zToTreeMap.put(z, tree); filteredTileCount += tileBoundsList.size(); } LOG.info( "buildRTrees: added bounds for {} out of {} tiles to {} trees", filteredTileCount, totalTileCount, zToTreeMap.size()); return zToTreeMap; }