package se.kodapan.osm.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author kalle * @since 2012-01-21 14:22 */ public class Grid { public static Logger log = LoggerFactory.getLogger(Grid.class); private double latitudeStep; private double longitudeStep; private long height; private long width; public Grid(double cellWidthKilometers) { this.width = (long) (6378.1d / cellWidthKilometers); this.height = width; init(); } public Grid(long width, long height) { this.height = height; this.width = width; init(); } public void init() { latitudeStep = 180d / (double) height; longitudeStep = 360d / (double) width; } public class Cell { private long top; private long left; public Cell(long top, long left) { this.top = top; this.left = left; } private Coordinate getNorthwest() { return new Coordinate(90 - (top * latitudeStep), -180 + (left * longitudeStep)); } public Envelope getEnvelope() { Coordinate southwest = getSouthwest(); Coordinate northeast = getNortheast(); return new Envelope(southwest, northeast); } public Coordinate getNortheast() { Coordinate northWest = getNorthwest(); return new Coordinate(getNorthwest().getLatitude(), northWest.getLongitude() + longitudeStep); } public Coordinate getSouthwest() { Coordinate northWest = getNorthwest(); return new Coordinate(getNorthwest().getLatitude() - latitudeStep, northWest.getLongitude()); } public long getIdentity() { return (top * width) + left; } public long getTop() { return top; } public long getLeft() { return left; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Cell cell = (Cell) o; if (left != cell.left) return false; if (top != cell.top) return false; return true; } @Override public int hashCode() { int result = (int) (top ^ (top >>> 32)); result = 31 * result + (int) (left ^ (left >>> 32)); return result; } } public Cell getCell(long id) { long top = (id / this.width); long left = (id - (top * this.height)); return new Cell(top, left); } public Cell getCell(Coordinate coordinate) { long top = (long) ((90d - coordinate.getLatitude()) / latitudeStep); long left = (long) ((coordinate.getLongitude() - -180d) / longitudeStep); return new Cell(top, left); } public long getHeight() { return height; } public long getWidth() { return width; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Grid grid = (Grid) o; if (height != grid.height) return false; if (Double.compare(grid.latitudeStep, latitudeStep) != 0) return false; if (Double.compare(grid.longitudeStep, longitudeStep) != 0) return false; if (width != grid.width) return false; return true; } @Override public int hashCode() { int result; long temp; temp = latitudeStep != +0.0d ? Double.doubleToLongBits(latitudeStep) : 0L; result = (int) (temp ^ (temp >>> 32)); temp = longitudeStep != +0.0d ? Double.doubleToLongBits(longitudeStep) : 0L; result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (int) (height ^ (height >>> 32)); result = 31 * result + (int) (width ^ (width >>> 32)); return result; } private class Envelope { private Coordinate southwest; private Coordinate northeast; private Envelope() { } private Envelope(Coordinate southwest, Coordinate northeast) { this.southwest = southwest; this.northeast = northeast; } private Coordinate getSouthwest() { return southwest; } private void setSouthwest(Coordinate southwest) { this.southwest = southwest; } private Coordinate getNortheast() { return northeast; } private void setNortheast(Coordinate northeast) { this.northeast = northeast; } } }