// License: GPL. Copyright 2009 by Dave Hansen, others package org.openstreetmap.josm.data.coor; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.projection.Projection; public class QuadTiling { public static int NR_LEVELS = 24; public static double WORLD_PARTS = (1 << NR_LEVELS); public static int MAX_OBJECTS_PER_LEVEL = 16; // has to be a power of 2 public static int TILES_PER_LEVEL_SHIFT = 2; public static int TILES_PER_LEVEL = 1<> shift) & 0x3; //if (debug) // out("shift: " + shift + " bits: " + bits); // remember x is the MSB if ((bits & 0x2) != 0) x += x_unit; if ((bits & 0x1) != 0) y += y_unit; x_unit /= 2; y_unit /= 2; shift -= 2; } x += X_BIAS; y += Y_BIAS; return new LatLon(y, x); } static long xy2tile(long x, long y) { long tile = 0; int i; for (i = NR_LEVELS-1; i >= 0; i--) { long xbit = ((x >> i) & 1); long ybit = ((y >> i) & 1); tile <<= 2; // Note that x is the MSB tile |= (xbit<<1) | ybit; } return tile; } static long coorToTile(LatLon coor) { return quadTile(coor); } static long lon2x(double lon) { //return Math.round((lon + 180.0) * QuadBuckets.WORLD_PARTS / 360.0)-1; long ret = (long)Math.floor((lon + 180.0) * WORLD_PARTS / 360.0); if (ret == WORLD_PARTS) ret--; return ret; } static long lat2y(double lat) { //return Math.round((lat + 90.0) * QuadBuckets.WORLD_PARTS / 180.0)-1; long ret = (long)Math.floor((lat + 90.0) * WORLD_PARTS / 180.0); if (ret == WORLD_PARTS) ret--; return ret; } static public long quadTile(LatLon coor) { return xy2tile(lon2x(coor.lon()), lat2y(coor.lat())); } static public int index(int level, long quad) { long mask = 0x00000003; int total_shift = TILES_PER_LEVEL_SHIFT*(NR_LEVELS-level-1); return (int)(mask & (quad >> total_shift)); } static public int index(Node n, int level) { LatLon coor = n.getCoor(); // The nodes that don't return coordinates will all get // stuck in a single tile. Hopefully there are not too // many of them if (coor == null) return 0; long quad = coorToTile(n.getCoor()); return index(level, quad); } }