package org.apache.lucene.spatial3d.geom;
public class GeoBBoxFactory {
private GeoBBoxFactory() {
}
public static GeoBBox makeGeoBBox(final PlanetModel planetModel, double topLat, double bottomLat, double leftLon, double rightLon) {
if (topLat > Math.PI * 0.5)
topLat = Math.PI * 0.5;
if (bottomLat < -Math.PI * 0.5)
bottomLat = -Math.PI * 0.5;
if (leftLon < -Math.PI)
leftLon = -Math.PI;
if (rightLon > Math.PI)
rightLon = Math.PI;
if ((Math.abs(leftLon + Math.PI) < Vector.MINIMUM_ANGULAR_RESOLUTION && Math.abs(rightLon - Math.PI) < Vector.MINIMUM_ANGULAR_RESOLUTION) ||
(Math.abs(rightLon + Math.PI) < Vector.MINIMUM_ANGULAR_RESOLUTION && Math.abs(leftLon - Math.PI) < Vector.MINIMUM_ANGULAR_RESOLUTION)) {
if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION && Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION)
return new GeoWorld(planetModel);
if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION || Math.abs(topLat + Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION)
return new GeoDegeneratePoint(planetModel, topLat, 0.0);
return new GeoDegenerateLatitudeZone(planetModel, topLat);
}
if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION)
return new GeoNorthLatitudeZone(planetModel, bottomLat);
else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION)
return new GeoSouthLatitudeZone(planetModel, topLat);
return new GeoLatitudeZone(planetModel, topLat, bottomLat);
}
double extent = rightLon - leftLon;
if (extent < 0.0)
extent += Math.PI * 2.0;
if (topLat == Math.PI * 0.5 && bottomLat == -Math.PI * 0.5) {
if (Math.abs(leftLon - rightLon) < Vector.MINIMUM_ANGULAR_RESOLUTION)
return new GeoDegenerateLongitudeSlice(planetModel, leftLon);
if (extent >= Math.PI)
return new GeoWideLongitudeSlice(planetModel, leftLon, rightLon);
return new GeoLongitudeSlice(planetModel, leftLon, rightLon);
}
if (Math.abs(leftLon - rightLon) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_ANGULAR_RESOLUTION)
return new GeoDegeneratePoint(planetModel, topLat, leftLon);
return new GeoDegenerateVerticalLine(planetModel, topLat, bottomLat, leftLon);
}
if (extent >= Math.PI) {
if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoDegeneratePoint(planetModel, topLat, 0.0);
} else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoDegeneratePoint(planetModel, bottomLat, 0.0);
}
return new GeoWideDegenerateHorizontalLine(planetModel, topLat, leftLon, rightLon);
}
if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoWideNorthRectangle(planetModel, bottomLat, leftLon, rightLon);
} else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoWideSouthRectangle(planetModel, topLat, leftLon, rightLon);
}
return new GeoWideRectangle(planetModel, topLat, bottomLat, leftLon, rightLon);
}
if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoDegeneratePoint(planetModel, topLat, 0.0);
} else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoDegeneratePoint(planetModel, bottomLat, 0.0);
}
return new GeoDegenerateHorizontalLine(planetModel, topLat, leftLon, rightLon);
}
if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoNorthRectangle(planetModel, bottomLat, leftLon, rightLon);
} else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_ANGULAR_RESOLUTION) {
return new GeoSouthRectangle(planetModel, topLat, leftLon, rightLon);
}
return new GeoRectangle(planetModel, topLat, bottomLat, leftLon, rightLon);
}
public static GeoBBox makeGeoBBox(final PlanetModel planetModel, LatLonBounds bounds) {
final double topLat = (bounds.checkNoTopLatitudeBound()) ? Math.PI * 0.5 : bounds.getMaxLatitude();
final double bottomLat = (bounds.checkNoBottomLatitudeBound()) ? -Math.PI * 0.5 : bounds.getMinLatitude();
final double leftLon = (bounds.checkNoLongitudeBound()) ? -Math.PI : bounds.getLeftLongitude();
final double rightLon = (bounds.checkNoLongitudeBound()) ? Math.PI : bounds.getRightLongitude();
return makeGeoBBox(planetModel, topLat, bottomLat, leftLon, rightLon);
}
}