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

org.hibernate.search.spatial.impl.Rectangle Maven / Gradle / Ivy

There is a newer version: 5.11.12.Final
Show newest version
/*
 * Hibernate Search, full-text search for your domain model
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.search.spatial.impl;

import org.hibernate.search.spatial.Coordinates;

/**
 * Bounding box for search area on Earth
 *
 * @author Nicolas Helleringer
 * @author Mathieu Perez
 */
public final class Rectangle {

	private final Point lowerLeft;
	private final Point upperRight;

	public Rectangle(Point lowerLeft, Point upperRight) {
		this.lowerLeft = lowerLeft;
		this.upperRight = upperRight;
	}

	/**
	 * Compute appropriate bounding box on Earth with pole and prime meridian crossing checks
	 *
	 * @param centerCoordinates of the search area
	 * @param radius of the search area
	 * @return a bounding box for the area
	 * @see Bouding box on Earth calculation
	 */
	public static Rectangle fromBoundingCircle(Coordinates centerCoordinates, double radius) {
		Point center = Point.fromCoordinates( centerCoordinates );
		// http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates
		double minimumLatitude, maximumLatitude;
		double minimumLongitude, maximumLongitude;

		if ( radius > center.getDistanceTo( GeometricConstants.NORTH_POLE ) ) {
			maximumLatitude = GeometricConstants.LATITUDE_DEGREE_MAX;
		}
		else {
			maximumLatitude = center.computeDestination( radius, GeometricConstants.HEADING_NORTH ).getLatitude();
		}

		if ( radius > center.getDistanceTo( GeometricConstants.SOUTH_POLE ) ) {
			minimumLatitude = GeometricConstants.LATITUDE_DEGREE_MIN;
		}
		else {
			minimumLatitude = center.computeDestination( radius, GeometricConstants.HEADING_SOUTH ).getLatitude();
		}

		if ( ( radius > 2 * Math.PI * GeometricConstants.EARTH_MEAN_RADIUS_KM * Math.cos(
				Math.toRadians(
						minimumLatitude
				)
		) ) || ( radius > 2 * Math.PI * GeometricConstants.EARTH_MEAN_RADIUS_KM * Math.cos(
				Math.toRadians(
						maximumLatitude
				)
		) ) ) {
			maximumLongitude = GeometricConstants.LONGITUDE_DEGREE_MAX;
			minimumLongitude = GeometricConstants.LONGITUDE_DEGREE_MIN;
		}
		else {
			Point referencePoint = Point.fromDegrees(
					Math.max(
							Math.abs( minimumLatitude ),
							Math.abs( maximumLatitude )
					), center.getLongitude()
			);
			maximumLongitude = referencePoint.computeDestination( radius, GeometricConstants.HEADING_EAST )
					.getLongitude();
			minimumLongitude = referencePoint.computeDestination( radius, GeometricConstants.HEADING_WEST )
					.getLongitude();
		}

		return new Rectangle(
				Point.fromDegreesInclusive( minimumLatitude, minimumLongitude ),
				Point.fromDegreesInclusive( maximumLatitude, maximumLongitude )
		);
	}

	public Point getLowerLeft() {
		return lowerLeft;
	}

	public Point getUpperRight() {
		return upperRight;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy