Space space = index.space();
int latColumn = index.firstSpatialArgument();
int lonColumn = latColumn + 1;
// The index column selector needs to select all the columns before the z column, and the z column itself.
IndexRowPrefixSelector indexColumnSelector = new IndexRowPrefixSelector(latColumn + 1);
IndexBound loBound = keyRange.lo();
ValueRecord loExpressions = loBound.boundExpressions(context, bindings);
// Compute z-value at beginning of forward and backward scans
TInstance latInstance = index.getAllColumns().get(latColumn).getColumn().getType();
TInstance lonInstance = index.getAllColumns().get(lonColumn).getColumn().getType();
BigDecimal lat = TBigDecimal.getWrapper(loExpressions.value(latColumn), latInstance).asBigDecimal();
BigDecimal lon = TBigDecimal.getWrapper(loExpressions.value(lonColumn), lonInstance).asBigDecimal();
zStart = Spatial.shuffle(space, lat.doubleValue(), lon.doubleValue());
// Cursors going forward from starting z value (inclusive), and backward from the same z value (exclusive)
int indexRowFields = physicalIndexRowType.nFields();
SpatialIndexValueRecord zForwardRow = new SpatialIndexValueRecord(indexRowFields);
SpatialIndexValueRecord zBackwardRow = new SpatialIndexValueRecord(indexRowFields);
SpatialIndexValueRecord zMaxRow = new SpatialIndexValueRecord(indexRowFields);
SpatialIndexValueRecord zMinRow = new SpatialIndexValueRecord(indexRowFields);
IndexBound zForward = new IndexBound(zForwardRow, indexColumnSelector);
IndexBound zBackward = new IndexBound(zBackwardRow, indexColumnSelector);
IndexBound zMax = new IndexBound(zMaxRow, indexColumnSelector);
IndexBound zMin = new IndexBound(zMinRow, indexColumnSelector);
// Take care of any equality restrictions before the spatial fields
zPosition = latColumn;
for (int f = 0; f < zPosition; f++) {
ValueSource eqValueSource = loExpressions.value(f);
zForwardRow.value(f, eqValueSource);