@Override public double getBinOverlap (TileIndex tile, BinIndex bin, Rectangle2D area) { Point2D lowerLeftRoot = new Point2D.Double(area.getMinX(), area.getMinY()); Point2D lowerLeftMercator = rootToTileMercator(lowerLeftRoot, tile.getLevel()); double left = (lowerLeftMercator.getX()-tile.getX())*tile.getXBins()-bin.getX(); double bottom = (tile.getYBins()-1) - (lowerLeftMercator.getY()-tile.getY())*tile.getYBins() - bin.getY(); Point2D upperRightRoot = new Point2D.Double(area.getMaxX(), area.getMaxY()); Point2D upperRightMercator = rootToTileMercator(upperRightRoot, tile.getLevel()); double right = (upperRightMercator.getX()-tile.getX())*tile.getXBins()-bin.getX(); double top = (tile.getYBins()-1) - (upperRightMercator.getY() - tile.getY())*tile.getYBins() - bin.getY(); // Top and bottom actually reversed, but since we take absolute values, it doesn't really matter. left = Math.min(Math.max(left, 0.0), 1.0); right = Math.min(Math.max(right, 0.0), 1.0); top = Math.min(Math.max(top, -1.0), 0.0); bottom = Math.min(Math.max(bottom, -1.0), 0.0); return Math.abs((right-left) * (top-bottom)); }
static public AnnotationTile getTileFromJSON( JSONObject json ) throws IllegalArgumentException { try { TileIndex index = new TileIndex( json.getInt("level"), json.getInt("x"), json.getInt("y"), AnnotationIndexer.NUM_BINS, AnnotationIndexer.NUM_BINS ); // create tile with empty bins DenseTileData<AnnotationBin> tile = new DenseTileData<>( index ); // for all binkeys Iterator<?> binKeys = json.keys(); while( binKeys.hasNext() ) { String binKey = (String)binKeys.next(); if( json.get(binKey) instanceof JSONObject ){ JSONObject bin = (JSONObject)json.get(binKey); BinIndex binIndex = BinIndex.fromString( binKey ); tile.setBin( binIndex.getX(), binIndex.getY(), getBinFromJSON( bin )); } } return new AnnotationTile( tile.getDefinition(), tile.getData() ); } catch ( Exception e ) { throw new IllegalArgumentException( e ); } }
private Map<Integer, Map> parseAggregations(Histogram date_agg, TileIndex tileIndex) { List<? extends Histogram.Bucket> dateBuckets = date_agg.getBuckets(); Map<Integer, Map> result = new HashMap<>(); long maxval = 0; for (Histogram.Bucket dateBucket : dateBuckets) { Histogram cluster_agg = dateBucket.getAggregations().get("yField"); List<? extends Histogram.Bucket> clusterBuckets = cluster_agg.getBuckets(); BinIndex xBinIndex = tilePyramid.rootToBin(dateBucket.getKeyAsNumber().doubleValue(), 0, tileIndex); int xBin = xBinIndex.getX(); Map<Integer,Long> intermediate = new HashMap<>(); result.put(xBin, intermediate); for( Histogram.Bucket clusterBucket : clusterBuckets) { //given the bin coordinates, see if there's any data in those bins, add values to existing bins BinIndex binIndex = tilePyramid.rootToBin(dateBucket.getKeyAsNumber().doubleValue(), clusterBucket.getKeyAsNumber().doubleValue(), tileIndex); int yBin = binIndex.getY(); if (result.containsKey(xBin) && result.get(xBin).containsKey(yBin)) { intermediate.put(yBin, (long) intermediate.get(yBin) + clusterBucket.getDocCount()); } else if (result.containsKey(xBin) && !(intermediate.containsKey(yBin))) { intermediate.put(yBin, clusterBucket.getDocCount()); } if (maxval < clusterBucket.getDocCount()){ maxval = clusterBucket.getDocCount(); } } } return result; }
int uniBinX = Math.min(Math.max(bin.getX(), 0), pow2*xBins-1); // restrict uni X bin to valid range tileX = uniBinX/xBins; tileLeft = tileX * xBins;
int index = binIndex.getX() + ( binIndex.getY() * tileIndex.getXBins() );
@Override public Rectangle2D getBinBounds(TileIndex tile, BinIndex bin) { long pow2 = 1L << tile.getLevel(); double tileXSize = (_maxX-_minX)/pow2; double tileYSize = (_maxY-_minY)/pow2; double binXSize = tileXSize/tile.getXBins(); double binYSize = tileYSize/tile.getYBins(); int adjustedBinY = tile.getYBins()-1-bin.getY(); return new Rectangle2D.Double(_minX+tileXSize*tile.getX()+binXSize*bin.getX(), _minY+tileYSize*tile.getY()+binYSize*adjustedBinY, binXSize, binYSize); }
public Rectangle2D getEPSG_900913Bounds (TileIndex tile, BinIndex bin) { int pow2 = 1 << tile.getLevel(); double tileIncrement = 1.0/pow2; double minX = tile.getX() * tileIncrement - 0.5; double minY = tile.getY() * tileIncrement - 0.5; double maxX, maxY; if (null != bin) { double binXInc = tileIncrement/tile.getXBins(); double binYInc = tileIncrement/tile.getYBins(); minX = minX + bin.getX()*binXInc; minY = minY + (tile.getYBins() - bin.getY()-1)*binYInc; maxX = minX + binXInc; maxY = minY + binYInc; } else { maxX = minX + tileIncrement; maxY = minY + tileIncrement; } // Our range is actually (-0.5, 0.5), not (-1.0, 1.0), so we need 2 x ScaleFactor return new Rectangle2D.Double (minX*2.0*EPSG_900913_SCALE_FACTOR, minY*2.0*EPSG_900913_SCALE_FACTOR, (maxX-minX)*2.0*EPSG_900913_SCALE_FACTOR, (maxY-minY)*2.0*EPSG_900913_SCALE_FACTOR); }
private Point getBinCoordinates (double x, double y) { Point2D point = new Point2D.Double(x, y); TileIndex tile = _pyramid.rootToTile(point, _level); if (tile.getXBins() != _numXBins && tile.getYBins() != _numYBins) { tile = new TileIndex(tile.getLevel(), tile.getX(), tile.getY(), _numXBins, _numYBins); } BinIndex bin = _pyramid.rootToBin(point, tile); return new Point(tile.getX()*tile.getXBins()+bin.getX(), tile.getY()*tile.getYBins()+(tile.getYBins()-1-bin.getY())); }
@Override public Rectangle2D getBinBounds (TileIndex tile, BinIndex bin) { int level = tile.getLevel(); double binXInc = 1.0/tile.getXBins(); double baseX = tile.getX()+bin.getX()*binXInc; double binYInc = 1.0/tile.getYBins(); double baseY = tile.getY()+(tile.getYBins()-1-bin.getY())*binYInc; double north = tileToLat(baseY + binYInc, level); double south = tileToLat(baseY, level); double east = tileToLon(baseX + binXInc, level); double west = tileToLon(baseX, level); return new Rectangle2D.Double(west, south, east-west, north-south); }
@Test public void testBounds () { int minBinX = 1000; int maxBinX = -1000; int minBinY = 1000; int maxBinY = -1000; for (int i=0; i<10000000; ++i) { double longitude = Math.random()*180-180; double latitude = Math.random()*90-90; Point2D pt = new Point2D.Double(longitude, latitude); TileIndex tile = _mercator.rootToTile(pt, 1); if (0 != tile.getX() || 0 != tile.getY()) continue; BinIndex bin = _mercator.rootToBin(pt, tile); if (bin.getX() < minBinX) minBinX = bin.getX(); if (bin.getX() > maxBinX) maxBinX = bin.getX(); if (bin.getY() < minBinY) minBinY = bin.getY(); if (bin.getY() > maxBinY) maxBinY = bin.getY(); } Assert.assertEquals(0, minBinX); Assert.assertEquals(0, minBinY); Assert.assertEquals(255, maxBinX); Assert.assertEquals(255, maxBinY); }
/** * Translates from a bin relative to the root position of this tile, to a * bin relative to the root position of the entire data set. * * @param tile * The tile in which this bin falls * @param bin * The bin relative to the root position of this tile (with * coordinates [0 to getXBins(), 0 to getYBins()]) * @return The bin relative to the root position of the entire data set * (with coordinates [0 to getXBins()*2^level, 0 to * getYBins()*2^level]) */ public static BinIndex tileBinIndexToUniversalBinIndex (TileIndex tile, BinIndex bin) { // Tiles go from lower left to upper right // Bins go from upper left to lower right int pow2 = 1 << tile.getLevel(); int tileLeft, tileTop; int xBins = tile.getXBins(); tileLeft = tile.getX() * xBins; int yBins = tile.getYBins(); tileTop = (pow2 - tile.getY() - 1) * yBins; return new BinIndex(tileLeft + bin.getX(), tileTop + bin.getY()); }
setValue(valueRecord, value); GenericRecord binRecord = new GenericData.Record(binSchema); binRecord.put("xIndex", index.getX()); binRecord.put("yIndex", index.getY()); binRecord.put("value", valueRecord);
List<Integer> actual = null; BinIndex baseTopUBin = TileIndex.tileBinIndexToUniversalBinIndex(topIdx, new BinIndex(x, y)); BinIndex baseUBin = new BinIndex(baseTopUBin.getX() * lf, baseTopUBin.getY() * lf); TileIndex baseTile = new TileIndex(b, 0, 0); for (int rx = 0; rx < lf; ++rx) { for (int ry = 0; ry < lf; ++ry) { BinIndex bin = new BinIndex(baseUBin.getX() + rx, baseUBin.getY() + ry); TileAndBinIndices tbi = TileIndex.universalBinIndexToTileBinIndex(baseTile, bin); TileData<List<Integer>> subTile = allTiles.get(b).get(tbi.getTile()); if (null != subTile) { List<Integer> subBin = subTile.getBin(tbi.getBin().getX(), tbi.getBin().getY()); actual = addLists(actual, subBin);