001: //=============================================================================
002: //=== Copyright (C) 2001-2007 Food and Agriculture Organization of the
003: //=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
004: //=== and United Nations Environment Programme (UNEP)
005: //===
006: //=== This program is free software; you can redistribute it and/or modify
007: //=== it under the terms of the GNU General Public License as published by
008: //=== the Free Software Foundation; either version 2 of the License, or (at
009: //=== your option) any later version.
010: //===
011: //=== This program is distributed in the hope that it will be useful, but
012: //=== WITHOUT ANY WARRANTY; without even the implied warranty of
013: //=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: //=== General Public License for more details.
015: //===
016: //=== You should have received a copy of the GNU General Public License
017: //=== along with this program; if not, write to the Free Software
018: //=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
019: //===
020: //=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
021: //=== Rome - Italy. email: geonetwork@osgeo.org
022: //==============================================================================
023:
024: package org.wfp.vam.intermap.kernel.map.mapServices;
025:
026: import java.util.List;
027: import org.jdom.Element;
028: import org.wfp.vam.intermap.kernel.map.mapServices.constants.MapServices;
029: import org.wfp.vam.intermap.kernel.map.mapServices.wms.schema.type.WMSBaseBoundingBox;
030:
031: public class BoundingBox {
032: // Bounding Box coordinates
033: private float northBound, southBound, eastBound, westBound;
034:
035: public BoundingBox() {
036: setDefault();
037: }
038:
039: public void setDefault() {
040: northBound = MapServices.DEFAULT_NORTH;
041: southBound = MapServices.DEFAULT_SOUTH;
042: eastBound = MapServices.DEFAULT_EAST;
043: westBound = MapServices.DEFAULT_WEST;
044: }
045:
046: public BoundingBox(WMSBaseBoundingBox bbox) {
047: this (bbox.getMaxy(), bbox.getMiny(), bbox.getMaxx(), bbox
048: .getMinx());
049: }
050:
051: public BoundingBox(float north, float south, float east, float west)
052: // throws Exception
053: {
054: // Throw an exception if not valid coordinates
055: // if (south >= north || north > Constants.MAX_LATITUDE
056: // || south < -Constants.MAX_LATITUDE)
057: // throw new Exception("Illegal bounding box");
058:
059: northBound = north;
060: southBound = south;
061: // if (Math.abs(west - east) > 360) {
062: // eastBound = Constants.DEFAULT_EAST;
063: // westBound = Constants.DEFAULT_WEST;
064: // }
065: // else {
066: eastBound = east;
067: westBound = west;
068: // }
069:
070: // IMPORTANT: Calculate the module of east and west
071: }
072:
073: public String toString() {
074: return ("N: " + northBound + " S: " + southBound + " E: "
075: + eastBound + " W: " + westBound);
076: }
077:
078: public float getNorth() {
079: return northBound;
080: }
081:
082: public float getSouth() {
083: return southBound;
084: }
085:
086: public float getEast() {
087: return eastBound;
088: }
089:
090: public float getWest() {
091: return westBound;
092: }
093:
094: public float getLongDiff() {
095: return eastBound - westBound;
096: }
097:
098: /**
099: * Centers the BoundingBox to the specified coordinates.
100: * If the resulting coordinates are not valid, moves to the
101: * nearest valid bounding box.
102: *
103: *
104: * @param latitude the new latitude
105: * @param longitude the new longitude
106: *
107: * @throws Exception
108: *
109: */
110: public BoundingBox moveTo(float x, float y)
111: // throws Exception
112: {
113: // Throw an exception if not valid coordinates
114: // if (Math.abs(latitude) > 90 || Math.abs(longitude) > 180)
115: // throw new Exception();
116:
117: float semiNS = (northBound - southBound) / 2;
118: float semiEW = Math.abs(eastBound - westBound) / 2;
119:
120: // Calculate the temporary coordinates (maybe not valid)
121: float tNorth = y + semiNS;
122: float tSouth = y - semiNS;
123: float tEast = x + semiEW;
124: float tWest = x - semiEW;
125:
126: // Fix if not valid coordinates
127: // if (tNorth > Constants.MAX_LATITUDE) {
128: // northBound = Constants.MAX_LATITUDE;
129: // southBound = tSouth - (tNorth - Constants.MAX_LATITUDE);
130: // }
131: // else {
132: // northBound = tNorth;
133: // }
134: // if (tSouth < - Constants.MAX_LATITUDE) {
135: // southBound = - Constants.MAX_LATITUDE;
136: // northBound = tNorth + (Constants.MAX_LATITUDE - tSouth);
137: // }
138: // else {
139: // southBound = tSouth;
140: // }
141:
142: northBound = tNorth;
143: southBound = tSouth;
144: eastBound = tEast;
145: westBound = tWest;
146:
147: return this ;
148: // IMPORTANT: Calculate the module of east and west
149: }
150:
151: public BoundingBox move(float x, float y) {
152: northBound = northBound + y;
153: southBound = southBound + y;
154: eastBound = eastBound + x;
155: westBound = westBound + x;
156:
157: return this ;
158: }
159:
160: /**
161: * Calculates the union of one or more bounding boxes. It still doesn't
162: * handle bounding boxes that cross the 12<sup>th</sup> meridian.
163: *
164: * @param v a Vector of BoundingBox
165: *
166: * @return a BoundingBox
167: *
168: * @throws Exception
169: *
170: */
171: public static BoundingBox union(List<BoundingBox> v) {
172: if (v.size() == 0) {
173: return new BoundingBox();
174: }
175:
176: BoundingBox bb = v.get(0);
177: for (int i = 1; i < v.size(); i++) {
178: BoundingBox t = v.get(i);
179: bb = new BoundingBox(Math.max(bb.getNorth(), t.northBound),
180: Math.min(bb.getSouth(), t.southBound), Math.max(bb
181: .getEast(), t.eastBound), Math.min(bb
182: .getWest(), t.westBound));
183: }
184:
185: return bb;
186: }
187:
188: public BoundingBox zoom(float factor) throws Exception {
189: if (factor == 0)
190: throw new Exception("Illegal zoom factor");
191: float deltaNS = Math.abs(northBound - southBound)
192: * (1 - (1 / factor));
193: float deltaEW = Math.abs(eastBound - westBound)
194: * (1 - (1 / factor));
195:
196: northBound = northBound - deltaNS / 2;
197: southBound = southBound + deltaNS / 2;
198:
199: if (eastBound > westBound) {
200: eastBound = eastBound - deltaEW / 2;
201: westBound = westBound + deltaEW / 2;
202: } else {
203: eastBound = eastBound + deltaEW / 2;
204: westBound = westBound - deltaEW / 2;
205: }
206:
207: if (Math.abs(eastBound - westBound) > MapServices.DEFAULT_EAST
208: - MapServices.DEFAULT_WEST) {
209: setDefault();
210: }
211:
212: return this ;
213: }
214:
215: public Element toElement() {
216: return new Element("extent").setAttribute("minx",
217: westBound + "").setAttribute("maxx", eastBound + "")
218: .setAttribute("miny", southBound + "").setAttribute(
219: "maxy", northBound + "");
220: }
221:
222: }
|