All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.eBusx.geo.BoundingBox Maven / Gradle / Ivy

//
// Copyright 2021 Charles W. Rapp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package net.sf.eBusx.geo;

import java.math.BigDecimal;
import net.sf.eBus.messages.EField;
import net.sf.eBus.util.Validator;


/**
 * A bounding box (usually shortened to bbox) is an area defined
 * by two longitudes and two latitudes, where:
 * 
    *
  • * Latitude is a decimal number between -90.0 and 90.0. *
  • *
  • * Longitude is a decimal number between -180.0 and 180.0. *
  • *
* Bounding box contains the minimum and maximum latitude and * longitude values which define the four box corners. *

* A bounding box is not an Open Street Map element and * therefore has no associated unique identifier. *

* * @author Charles W. Rapp */ public final class BoundingBox extends EField { //--------------------------------------------------------------- // Member data. // //----------------------------------------------------------- // Constants. // /** * Serialization version identifier. */ private static final long serialVersionUID = 0x000100L; //----------------------------------------------------------- // Statics. // //----------------------------------------------------------- // Locals. // /** * Minimum latitude sets the southern east-west boundary. */ public final BigDecimal minLatitude; /** * Maximum latitude sets the northern east-west boundary. */ public final BigDecimal maxLatitude; /** * Minimum longitude sets the western north-south boundary. */ public final BigDecimal minLongitude; /** * Minimum longitude sets the eastern north-south boundary. */ public final BigDecimal maxLongitude; //--------------------------------------------------------------- // Member methods. // //----------------------------------------------------------- // Constructors. // /** * Creates a new bounding box instance based on the builder * settings. * @param builder contains bounding box settings. */ private BoundingBox(final Builder builder) { super (builder); this.minLatitude = builder.mMinLatitude; this.maxLatitude = builder.mMaxLatitude; this.minLongitude = builder.mMinLongitude; this.maxLongitude = builder.mMaxLongitude; } // end of BoundingBox(Builder) // // end of Constructors. //----------------------------------------------------------- //----------------------------------------------------------- // Object Method Overrides. // /** * Returns text containing the four bounding box positions. * @return bounding box textual representation. */ @Override public String toString() { final StringBuilder retval = new StringBuilder(); return (retval.append("[lat={min=") .append(minLatitude.toPlainString()) .append(", max=") .append(maxLatitude.toPlainString()) .append("}, long={min=") .append(minLongitude.toPlainString()) .append(", max=") .append(maxLongitude.toPlainString()) .append("}]") .toString()); } // end of toString() // // end of Object Method Overrides. //----------------------------------------------------------- /** * Returns a new bounding box builder instance. It is * recommended that a new builder instance be used to * create a new bounding box and that builders should not * be re-used. * @return bounding box builder instance. */ public static Builder builder() { return (new Builder()); } // end of builder() //--------------------------------------------------------------- // Inner classes. // /** * A {@code Builder} instance is the only was to create a * {@code BoundingBox} instance. The only way to obtain * a {@code Builder} instance is via * {@link BoundingBox#builder()}. Use the builder instance * to set the bounding box latitude and longitude points * and then call {@link Builder#build()} to generate the * bounding box instance. *

* It is recommended that a new builder instance be used for * each new bounding box instance. Builder instance re-use is * discouraged. *

*/ public static final class Builder extends EField.Builder { //----------------------------------------------------------- // Member data. // //------------------------------------------------------- // Locals. // private BigDecimal mMinLatitude; private BigDecimal mMaxLatitude; private BigDecimal mMinLongitude; private BigDecimal mMaxLongitude; //----------------------------------------------------------- // Member methods. // //------------------------------------------------------- // Constructors. // private Builder() { super (BoundingBox.class); } // end of Builder() // // end of Constructors. //------------------------------------------------------- //------------------------------------------------------- // Builder Method Overrides. // /** * Checks if: *
    *
  1. * all four bounding box points are set, *
  2. *
  3. * minimum latitude ≤ maximum latitude, and *
  4. *
  5. * minimum longitude ≤ maximum longitude. *
  6. *
* @param problems add each detected problem to this * validator. * @return {@code problem} */ @Override protected Validator validate(final Validator problems) { return (super.validate(problems) .requireNotNull( mMinLatitude, "minLatitude") .requireNotNull( mMaxLatitude, "maxLatitude") .requireNotNull( mMinLongitude, "minLongitude") .requireNotNull( mMaxLongitude, "maxLongitude") // Verify latitudes and longitudes are // in the proper order. .requireTrue( (a, b) -> (a.compareTo(b) <= 0), mMinLatitude, mMaxLatitude, "minLatitude", "maxLatitude", "minLatitude > maxLatitude") .requireTrue( (a, b) -> (a.compareTo(b) <= 0), mMinLongitude, mMaxLongitude, "minLongitude", "maxLongitude", "minLongitude > maxLongitude")); } // end of validate(Validator) /** * Returns a new bounding box instance based on this * builder's settings. * @return new bounding box instance. */ @Override protected BoundingBox buildImpl() { return (new BoundingBox(this)); } // end of buildImpl() // // end of Builder Method Overrides. //------------------------------------------------------- //------------------------------------------------------- // Set Methods. // /** * Sets southern bounding box latitude. Returns * {@code this Builder} instance so that builder method * calls can be chained. * @param min southern or minimum latitude. * @return {@code this Builder} instance. * @throws NullPointerException * if {@code min} is {@code null}. * @throws IllegalArgumentException * if {@code min} < {@link GeoObject#MIN_LATITUDE} or * > {@link GeoObject#MAX_LATITUDE}. */ public Builder minLatitude(final BigDecimal min) { mMinLatitude = GeoObject.validateLatitude(min); return (this); } // end of minLatitude(BigDecimal) /** * Sets northern bounding box latitude. Returns * {@code this Builder} instance so that builder method * calls can be chained. * @param max northern or maximum latitude. * @return {@code this Builder} instance. * @throws NullPointerException * if {@code max} is {@code null}. * @throws IllegalArgumentException * if {@code max} < {@link GeoObject#MIN_LATITUDE} or * > {@link GeoObject#MAX_LATITUDE}. */ public Builder maxLatitude(final BigDecimal max) { mMaxLatitude = GeoObject.validateLatitude(max); return (this); } // end of maxLatitude(BigDecimal) /** * Sets western bounding box longitude. Returns * {@code this Builder} instance so that builder method * calls can be chained. * @param min western or minimum latitude. * @return {@code this Builder} instance. * @throws NullPointerException * if {@code min} is {@code null}. * @throws IllegalArgumentException * if {@code min} < {@link GeoObject#MIN_LONGITUDE} or * > {@link GeoObject#MAX_LONGITUDE}. */ public Builder minLongitude(final BigDecimal min) { mMinLongitude = GeoObject.validateLongitude(min); return (this); } // end of minLongitude(BigDecimal) /** * Sets eastern bounding box longitude. Returns * {@code this Builder} instance so that builder method * calls can be chained. * @param max eastern or maximum latitude. * @return {@code this Builder} instance. * @throws NullPointerException * if {@code max} is {@code null}. * @throws IllegalArgumentException * if {@code max} < {@link GeoObject#MIN_LONGITUDE} or * > {@link GeoObject#MAX_LONGITUDE}. */ public Builder maxLongitude(final BigDecimal max) { mMaxLongitude = GeoObject.validateLongitude(max); return (this); } // end of maxLongitude(BigDecimal) // // end of Set Methods. //------------------------------------------------------- } // end of class Builder } // end of class BoundingBox




© 2015 - 2024 Weber Informatics LLC | Privacy Policy