package com.esri.hadoop.hive; import com.esri.core.geometry.Envelope; public class BinUtils { final long numCols; final double extentMin; final double extentMax; final double binSize; public BinUtils(double binSize) { this.binSize = binSize; // absolute max number of rows/columns we can have long maxBinsPerAxis = (long) Math.sqrt(Long.MAX_VALUE); // a smaller binSize gives us a smaller extent width and height that // can be addressed by a single 64 bit long double size = (binSize < 1) ? maxBinsPerAxis * binSize : maxBinsPerAxis; extentMax = size/2; extentMin = extentMax - size; numCols = (long)(Math.ceil(size / binSize)); } /** * Gets bin ID from a point. * * @param x * @param y * @return */ public long getId(double x, double y) { double down = (extentMax - y) / binSize; double over = (x - extentMin) / binSize; return ((long)down * numCols) + (long)over; } /** * Gets the envelope for the bin ID. * * @param binId * @param envelope */ public void queryEnvelope(long binId, Envelope envelope) { long down = binId / numCols; long over = binId % numCols; double xmin = extentMin + (over * binSize); double xmax = xmin + binSize; double ymax = extentMax - (down * binSize); double ymin = ymax - binSize; envelope.setCoords(xmin, ymin, xmax, ymax); } /** * Gets the envelope for the bin that contains the x,y coords. * * @param x * @param y * @param envelope */ public void queryEnvelope(double x, double y, Envelope envelope) { double down = (extentMax - y) / binSize; double over = (x - extentMin) / binSize; double xmin = extentMin + (over * binSize); double xmax = xmin + binSize; double ymax = extentMax - (down * binSize); double ymin = ymax - binSize; envelope.setCoords(xmin, ymin, xmax, ymax); } }