/******************************************************************************* * Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com) * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v3 * which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt ******************************************************************************/ package com.opendoorlogistics.core.gis.map; import java.util.List; import com.opendoorlogistics.api.geometry.LatLong; import com.opendoorlogistics.api.tables.beans.annotations.ODLColumnOrder; import com.opendoorlogistics.core.gis.map.data.DrawableObject; import com.opendoorlogistics.core.gis.map.data.LatLongBoundingBox; import com.opendoorlogistics.core.gis.map.data.LatLongImpl; import com.opendoorlogistics.core.tables.beans.BeanMappedRowImpl; import com.opendoorlogistics.core.utils.DoubleRange; /** * A view is a defined as a long-lat box (assumes a projection where long lats are treated as cartesian). * * @author Phil * */ public class View extends BeanMappedRowImpl{ private static final double EXPAND_FRACTION = 1.1; private static final double DEFAULT_ANGLE_DEGREES_WHEN_ZERO_SEPARATION = 0.1; private double minLongitude; private double maxLongitude; private double minLatitude; private double maxLatitude; public View() { } public View(double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) { super(); this.minLatitude = minLatitude; this.maxLatitude = maxLatitude; this.minLongitude = minLongitude; this.maxLongitude = maxLongitude; } public double getMinLongitude() { return minLongitude; } @ODLColumnOrder(3) public void setMinLongitude(double minLongitude) { this.minLongitude = minLongitude; } public double getMaxLongitude() { return maxLongitude; } @ODLColumnOrder(4) public void setMaxLongitude(double maxLongitude3) { this.maxLongitude = maxLongitude3; } public double getMinLatitude() { return minLatitude; } @ODLColumnOrder(1) public void setMinLatitude(double minLatitude) { this.minLatitude = minLatitude; } public double getMaxLatitude() { return maxLatitude; } @ODLColumnOrder(2) public void setMaxLatitude(double maxLatitude) { this.maxLatitude = maxLatitude; } public LatLong getCentre() { return new LatLongImpl(0.5 * (minLatitude + maxLatitude), 0.5 * (minLongitude + maxLongitude)); } public static View createView(List<? extends DrawableObject> pnts){ return createView(pnts, EXPAND_FRACTION, DEFAULT_ANGLE_DEGREES_WHEN_ZERO_SEPARATION); } private static View createView(List<? extends DrawableObject> drawables, double expandFraction, double degreesWhenZeroSeparation){ LatLongBoundingBox llbox = MapUtils.getLatLongBoundingBox(drawables, null); if(llbox.isValid()){ DoubleRange lats = llbox.getLatRange(); DoubleRange lngs = llbox.getLngRange(); lats.multiply(expandFraction); lngs.multiply(expandFraction); View view = new View(lats.getMin(), lats.getMax(), lngs.getMin(), lngs.getMax()); // check for zero dimension views if (view.getMinLongitude() == view.getMaxLongitude()) { double centre = 0.5 * (view.getMinLongitude() + view.getMaxLongitude()); view.setMinLongitude(Math.max(-180, centre - degreesWhenZeroSeparation)); view.setMaxLongitude(Math.min(+180, centre + degreesWhenZeroSeparation)); } if (view.getMinLatitude() == view.getMaxLatitude()) { double centre = 0.5 * (view.getMinLatitude() + view.getMaxLatitude()); view.setMinLatitude(Math.max(-90, centre - degreesWhenZeroSeparation)); view.setMaxLatitude(Math.min(+90, centre + degreesWhenZeroSeparation)); } return view; } // default view return new View(-1, 1, -1, 1); } public static View createViewWithMinSpans(List<? extends DrawableObject> drawables, double minSpanLat, double minSpanLong){ LatLongBoundingBox llBox = MapUtils.getLatLongBoundingBox(drawables, null); DoubleRange lats = llBox.getLatRange(); DoubleRange lngs = llBox.getLngRange(); if(lats.isValid() && lngs.isValid()){ lats.multiply(EXPAND_FRACTION); lngs.multiply(EXPAND_FRACTION); if(lats.getLength() < minSpanLat){ lats = new DoubleRange(lats.getCentre() - 0.5*minSpanLat, lats.getCentre() + 0.5*minSpanLat); } if(lngs.getLength() < minSpanLong){ lngs = new DoubleRange(lngs.getCentre() - 0.5*minSpanLong, lngs.getCentre() + 0.5*minSpanLong); } View view = new View(lats.getMin(), lats.getMax(), lngs.getMin(), lngs.getMax()); return view; } return null; } @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(maxLatitude); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(maxLongitude); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(minLatitude); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(minLongitude); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; View other = (View) obj; if (Double.doubleToLongBits(maxLatitude) != Double.doubleToLongBits(other.maxLatitude)) return false; if (Double.doubleToLongBits(maxLongitude) != Double.doubleToLongBits(other.maxLongitude)) return false; if (Double.doubleToLongBits(minLatitude) != Double.doubleToLongBits(other.minLatitude)) return false; if (Double.doubleToLongBits(minLongitude) != Double.doubleToLongBits(other.minLongitude)) return false; return true; } }