001/*
002 * Copyright 2014 Global Biodiversity Information Facility (GBIF)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.gbif.api.model.registry.eml.geospatial;
017
018import java.io.Serializable;
019import java.util.Locale;
020
021
022/**
023 * Geographic coverage geometry in the form of 4 sided bounding box.
024 */
025public class BoundingBox implements Serializable, Geometry {
026
027  private static final long serialVersionUID = 9101833933868378174L;
028
029  private static final int MIN_MIN_LONGITUDE = -180;
030  private static final int MAX_MAX_LONGITUDE = 180;
031
032  private static final int MIN_MIN_LATITUDE = -90;
033  private static final int MAX_MAX_LATITUDE = 90;
034
035  private double minLatitude;
036  private double maxLatitude;
037  private double minLongitude;
038  private double maxLongitude;
039  private boolean isGlobalCoverage;
040
041
042  public BoundingBox() {
043  }
044
045  public BoundingBox(double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) {
046    this.minLatitude = minLatitude;
047    this.maxLatitude = maxLatitude;
048    this.minLongitude = minLongitude;
049    this.maxLongitude = maxLongitude;
050    this.isGlobalCoverage = checkIsGlobalCoverage(minLatitude, maxLatitude, minLongitude, maxLongitude);
051  }
052
053  public double getMaxLatitude() {
054    return maxLatitude;
055  }
056
057  public void setMaxLatitude(double maxLatitude) {
058    this.maxLatitude = maxLatitude;
059  }
060
061  public double getMaxLongitude() {
062    return maxLongitude;
063  }
064
065  public void setMaxLongitude(double maxLongitude) {
066    this.maxLongitude = maxLongitude;
067  }
068
069  public double getMinLatitude() {
070    return minLatitude;
071  }
072
073  public void setMinLatitude(double minLatitude) {
074    this.minLatitude = minLatitude;
075  }
076
077  public double getMinLongitude() {
078    return minLongitude;
079  }
080
081  public void setMinLongitude(double minLongitude) {
082    this.minLongitude = minLongitude;
083  }
084
085  @Override
086  public String toWellKnownText() {
087    return String.format(Locale.ENGLISH, "POLYGON ((%f %f, %f %f, %f %f, %f %f))",
088                         minLongitude,
089                         minLatitude,
090                         minLongitude,
091                         maxLatitude,
092                         maxLongitude,
093                         maxLatitude,
094                         maxLongitude,
095                         minLatitude);
096  }
097
098  /**
099   * @return whether the BoundingBox represents global coverage
100   */
101  public boolean isGlobalCoverage() {
102    return isGlobalCoverage;
103  }
104
105  /**
106   * Set whether this binding box represents global coverage or not. Setter ensures all 4 required params are provided.
107   *
108   * @param minLatitude  min latitude
109   * @param maxLatitude  max latitude
110   * @param minLongitude min longitude
111   * @param maxLongitude max longitude
112   */
113  public void setGlobalCoverage(double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) {
114    isGlobalCoverage = checkIsGlobalCoverage(minLatitude, maxLatitude, minLongitude, maxLongitude);
115  }
116
117  /**
118   * Determine whether the bounding box represents global coverage. This is the case, when all North, East, South,
119   * and West lines represent the maximum possible degree values (90, 180, -90, -180).
120   *
121   * @param minLatitude  min latitude
122   * @param maxLatitude  max latitude
123   * @param minLongitude min longitude
124   * @param maxLongitude max longitude
125   *
126   * @return whether the bounding box represents global coverage
127   */
128  private boolean checkIsGlobalCoverage(
129    double minLatitude, double maxLatitude, double minLongitude, double maxLongitude
130  ) {
131    return minLatitude == MIN_MIN_LATITUDE
132           && maxLatitude == MAX_MAX_LATITUDE
133           && minLongitude == MIN_MIN_LONGITUDE
134           && maxLongitude == MAX_MAX_LONGITUDE;
135  }
136
137}