public static SearchResult search()

in baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/PackedRTree.java [332:403]


  public static SearchResult search(
      InputStream stream,
      int start,
      int numItems,
      int nodeSize,
      Envelope rect) throws IOException {
    LittleEndianDataInputStream data = new LittleEndianDataInputStream(stream);
    int dataPos = 0;
    int skip;
    List<SearchHit> hits = new ArrayList<>();
    double minX = rect.getMinX();
    double minY = rect.getMinY();
    double maxX = rect.getMaxX();
    double maxY = rect.getMaxY();
    List<Pair<Integer, Integer>> levelBounds = generateLevelBounds(numItems, nodeSize);
    int leafNodesOffset = levelBounds.get(0).first;
    int numNodes = levelBounds.get(0).second;
    Deque<QueueItem> queue = new LinkedList<QueueItem>();
    queue.add(new QueueItem(0, levelBounds.size() - 1));
    while (!queue.isEmpty()) {
      QueueItem stackItem = queue.pop();
      int nodeIndex = (int) stackItem.nodeIndex;
      int level = stackItem.level;
      boolean isLeafNode = nodeIndex >= numNodes - numItems;
      // find the end index of the node
      int levelBound = levelBounds.get(level).second;
      int end = Math.min(nodeIndex + nodeSize, levelBound);
      int nodeStart = nodeIndex * NODE_ITEM_LEN;
      skip = nodeStart - dataPos;
      if (skip > 0) {
        skipNBytes(data, skip);
        dataPos += skip;
      }
      // search through child nodes
      for (int pos = nodeIndex; pos < end; pos++) {
        int offset = nodeStart + ((pos - nodeIndex) * NODE_ITEM_LEN);
        skip = offset - dataPos;
        if (skip > 0) {
          skipNBytes(data, skip);
          dataPos += skip;
        }
        double nodeMinX = data.readDouble();
        dataPos += 8;
        if (maxX < nodeMinX) {
          continue;
        }
        double nodeMinY = data.readDouble();
        dataPos += 8;
        if (maxY < nodeMinY) {
          continue;
        }
        double nodeMaxX = data.readDouble();
        dataPos += 8;
        if (minX > nodeMaxX) {
          continue;
        }
        double nodeMaxY = data.readDouble();
        dataPos += 8;
        if (minY > nodeMaxY) {
          continue;
        }
        long indexOffset = data.readLong();
        dataPos += 8;
        if (isLeafNode) {
          hits.add(new SearchHit(indexOffset, (long) pos - leafNodesOffset));
        } else {
          queue.add(new QueueItem(indexOffset, level - 1));
        }
      }
    }
    return new SearchResult(hits, dataPos);
  }