@Override
 public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
   LeafReader reader = context.reader();
   FieldInfo info = reader.getFieldInfos().fieldInfo(field);
   if (info != null) {
     Geo3DDocValuesField.checkCompatible(info);
   }
   currentDocs = DocValues.getSortedNumeric(reader, field);
   return this;
 }
 double computeMinimumDistance(final int doc) throws IOException {
   if (doc > currentDocs.docID()) {
     currentDocs.advance(doc);
   }
   double minValue = Double.POSITIVE_INFINITY;
   if (doc == currentDocs.docID()) {
     final int numValues = currentDocs.docValueCount();
     for (int i = 0; i < numValues; i++) {
       final long encoded = currentDocs.nextValue();
       final double distance =
           distanceShape.computeDistance(
               DistanceStyle.ARC,
               Geo3DDocValuesField.decodeXValue(encoded),
               Geo3DDocValuesField.decodeYValue(encoded),
               Geo3DDocValuesField.decodeZValue(encoded));
       minValue = Math.min(minValue, distance);
     }
   }
   return minValue;
 }
  @Override
  public int compareBottom(int doc) throws IOException {
    if (doc > currentDocs.docID()) {
      currentDocs.advance(doc);
    }
    if (doc < currentDocs.docID()) {
      return Double.compare(bottomDistance, Double.POSITIVE_INFINITY);
    }

    int numValues = currentDocs.docValueCount();
    assert numValues > 0;

    int cmp = -1;
    for (int i = 0; i < numValues; i++) {
      long encoded = currentDocs.nextValue();

      // Test against bounds.
      // First we need to decode...
      final double x = Geo3DDocValuesField.decodeXValue(encoded);
      final double y = Geo3DDocValuesField.decodeYValue(encoded);
      final double z = Geo3DDocValuesField.decodeZValue(encoded);

      if (x > priorityQueueBounds.getMaximumX()
          || x < priorityQueueBounds.getMinimumX()
          || y > priorityQueueBounds.getMaximumY()
          || y < priorityQueueBounds.getMinimumY()
          || z > priorityQueueBounds.getMaximumZ()
          || z < priorityQueueBounds.getMinimumZ()) {
        continue;
      }

      cmp =
          Math.max(
              cmp,
              Double.compare(
                  bottomDistance, distanceShape.computeDistance(DistanceStyle.ARC, x, y, z)));
    }
    return cmp;
  }