diff options
Diffstat (limited to 'main/src/cgeo/geocaching/geopoint/Viewport.java')
| -rw-r--r-- | main/src/cgeo/geocaching/geopoint/Viewport.java | 125 |
1 files changed, 86 insertions, 39 deletions
diff --git a/main/src/cgeo/geocaching/geopoint/Viewport.java b/main/src/cgeo/geocaching/geopoint/Viewport.java index 390bdb4..18c8342 100644 --- a/main/src/cgeo/geocaching/geopoint/Viewport.java +++ b/main/src/cgeo/geocaching/geopoint/Viewport.java @@ -1,7 +1,5 @@ package cgeo.geocaching.geopoint; -import cgeo.geocaching.Settings; -import cgeo.geocaching.utils.Log; public class Viewport { @@ -10,19 +8,27 @@ public class Viewport { public final Geopoint bottomLeft; public final Geopoint topRight; - public Viewport(final Geopoint bottomLeft, final Geopoint topRight) { - this.bottomLeft = bottomLeft; - this.topRight = topRight; - this.center = new Geopoint((bottomLeft.getLatitude() + topRight.getLatitude()) / 2, - (bottomLeft.getLongitude() + topRight.getLongitude()) / 2); + public Viewport(final Geopoint gp1, final Geopoint gp2) { + this.bottomLeft = new Geopoint(Math.min(gp1.getLatitude(), gp2.getLatitude()), + Math.min(gp1.getLongitude(), gp2.getLongitude())); + this.topRight = new Geopoint(Math.max(gp1.getLatitude(), gp2.getLatitude()), + Math.max(gp1.getLongitude(), gp2.getLongitude())); + this.center = new Geopoint((gp1.getLatitude() + gp2.getLatitude()) / 2, + (gp1.getLongitude() + gp2.getLongitude()) / 2); } public Viewport(final Geopoint center, final double latSpan, final double lonSpan) { this.center = center; final double centerLat = center.getLatitude(); final double centerLon = center.getLongitude(); - bottomLeft = new Geopoint(centerLat - latSpan / 2, centerLon - lonSpan / 2); - topRight = new Geopoint(centerLat + latSpan / 2, centerLon + lonSpan / 2); + final double latHalfSpan = Math.abs(latSpan) / 2; + final double lonHalfSpan = Math.abs(lonSpan) / 2; + bottomLeft = new Geopoint(centerLat - latHalfSpan, centerLon - lonHalfSpan); + topRight = new Geopoint(centerLat + latHalfSpan, centerLon + lonHalfSpan); + } + + public Viewport(final double lat1, final double lat2, final double lon1, final double lon2) { + this(new Geopoint(lat1, lon1), new Geopoint(lat2, lon2)); } public double getLatitudeMin() { @@ -45,12 +51,39 @@ public class Viewport { return center; } + public double getLatitudeSpan() { + return getLatitudeMax() - getLatitudeMin(); + } + + public double getLongitudeSpan() { + return getLongitudeMax() - getLongitudeMin(); + } + + public boolean isInViewport(final Geopoint coords) { + + return coords.getLongitudeE6() >= bottomLeft.getLongitudeE6() + && coords.getLongitudeE6() <= topRight.getLongitudeE6() + && coords.getLatitudeE6() >= bottomLeft.getLatitudeE6() + && coords.getLatitudeE6() <= topRight.getLatitudeE6(); + } + @Override public String toString() { return "(" + bottomLeft.toString() + "," + topRight.toString() + ")"; } /** + * Check whether another viewport is fully included into the current one. + * + * @param vp + * the other viewport + * @return true if the vp is fully included into this one, false otherwise + */ + public boolean includes(final Viewport vp) { + return isInViewport(vp.bottomLeft) && isInViewport(vp.topRight); + } + + /** * Check if coordinates are located in a viewport (defined by its center and span * in each direction). * @@ -66,9 +99,11 @@ public class Viewport { * the coordinates to check * @return true if the coordinates are in the viewport */ + // FIXME: this static method has nothing to do here and should be used with a viewport, not some int numbers, + // when CGeoMap.java gets rewritten public static boolean isCacheInViewPort(int centerLat, int centerLon, int spanLat, int spanLon, final Geopoint coords) { - return 2 * Math.abs(coords.getLatitudeE6() - centerLat) <= Math.abs(spanLat) && - 2 * Math.abs(coords.getLongitudeE6() - centerLon) <= Math.abs(spanLon); + final Viewport viewport = new Viewport(new Geopoint(centerLat / 1e6, centerLon / 1e6), spanLat / 1e6, spanLon / 1e6); + return viewport.isInViewport(coords); } /** @@ -87,36 +122,48 @@ public class Viewport { * @param spanLon2 * @return */ + // FIXME: this static method has nothing to do here and should be used with a viewport, not some int numbers, + // when CGeoMap.java gets rewritten public static boolean isInViewPort(int centerLat1, int centerLon1, int centerLat2, int centerLon2, int spanLat1, int spanLon1, int spanLat2, int spanLon2) { - try { - final int left1 = centerLat1 - (spanLat1 / 2); - final int left2 = centerLat2 - (spanLat2 / 2); - if (left2 <= left1) { - return false; - } - - final int right1 = centerLat1 + (spanLat1 / 2); - final int right2 = centerLat2 + (spanLat2 / 2); - if (right2 >= right1) { - return false; - } - - final int top1 = centerLon1 + (spanLon1 / 2); - final int top2 = centerLon2 + (spanLon2 / 2); - if (top2 >= top1) { - return false; - } - - final int bottom1 = centerLon1 - (spanLon1 / 2); - final int bottom2 = centerLon2 - (spanLon2 / 2); - if (bottom2 <= bottom1) { - return false; - } - - return true; - } catch (Exception e) { - Log.e(Settings.tag, "Viewport.isInViewPort: " + e.toString()); + final Viewport outer = new Viewport(new Geopoint(centerLat1 / 1e6, centerLon1 / 1e6), spanLat1 / 1e6, spanLon1 / 1e6); + final Viewport inner = new Viewport(new Geopoint(centerLat2 / 1e6, centerLon2 / 1e6), spanLat2 / 1e6, spanLon2 / 1e6); + return outer.includes(inner); + } + + /** + * Return the "where" part of the string appropriate for a SQL query. + * + * @return the string without the "where" keyword + */ + public String sqlWhere() { + return "latitude >= " + getLatitudeMin() + " and " + + "latitude <= " + getLatitudeMax() + " and " + + "longitude >= " + getLongitudeMin() + " and " + + "longitude <= " + getLongitudeMax(); + } + + /** + * Return a widened or shrunk viewport. + * + * @param factor + * multiplicative factor for the latitude and longitude span (> 1 to widen, < 1 to shrink) + * @return a widened or shrunk viewport + */ + public Viewport resize(final double factor) { + return new Viewport(getCenter(), getLatitudeSpan() * factor, getLongitudeSpan() * factor); + } + + @Override + public boolean equals(final Object other) { + if (other == null || !(other instanceof Viewport)) { return false; } + final Viewport vp = (Viewport) other; + return bottomLeft.equals(vp.bottomLeft) && topRight.equals(vp.topRight); + } + + @Override + public int hashCode() { + return bottomLeft.hashCode() ^ topRight.hashCode(); } } |
