private List<IndexKeyRange> zKeyRanges(QueryContext context, IndexKeyRange keyRange)
{
List<IndexKeyRange> zKeyRanges = new ArrayList<>();
Index index = keyRange.indexRowType().index();
IndexBound loBound = keyRange.lo();
IndexBound hiBound = keyRange.hi();
ValueRecord loExpressions = loBound.boundExpressions(context, bindings);
ValueRecord hiExpressions = hiBound.boundExpressions(context, bindings);
// Only 2d, lat/lon supported for now
double xLo, xHi, yLo, yHi;
TInstance xinst = index.getAllColumns().get(latColumn).getColumn().getType();
TInstance yinst = index.getAllColumns().get(lonColumn).getColumn().getType();
xLo = TBigDecimal.getWrapper(loExpressions.value(latColumn), xinst).asBigDecimal().doubleValue();
xHi = TBigDecimal.getWrapper(hiExpressions.value(latColumn), xinst).asBigDecimal().doubleValue();
yLo = TBigDecimal.getWrapper(loExpressions.value(lonColumn), yinst).asBigDecimal().doubleValue();
yHi = TBigDecimal.getWrapper(hiExpressions.value(lonColumn), yinst).asBigDecimal().doubleValue();
SpatialObject box = BoxLatLon.newBox(xLo, xHi, yLo, yHi);
long[] zValues = new long[box.maxZ()];
space.decompose(box, zValues);
for (int i = 0; i < zValues.length; i++) {
long z = zValues[i];
if (z != -1L) {
IndexRowType physicalRowType = keyRange.indexRowType().physicalRowType();
int indexRowFields = physicalRowType.nFields();
SpatialIndexValueRecord zLoRow = new SpatialIndexValueRecord(indexRowFields);
SpatialIndexValueRecord zHiRow = new SpatialIndexValueRecord(indexRowFields);
IndexBound zLo = new IndexBound(zLoRow, indexColumnSelector);
IndexBound zHi = new IndexBound(zHiRow, indexColumnSelector);
// Take care of any equality restrictions before the spatial fields
for (int f = 0; f < latColumn; f++) {
ValueSource eqValueSource = loExpressions.value(f);
zLoRow.value(f, eqValueSource);
zHiRow.value(f, eqValueSource);