Package uk.ac.rdg.resc.edal.util
Class GISUtils
- java.lang.Object
-
- uk.ac.rdg.resc.edal.util.GISUtils
-
- All Implemented Interfaces:
ObjectFactory
public final class GISUtils extends Object implements ObjectFactory
A class containing static methods which are useful for GIS operations. Also implementsObjectFactory
so that it can be used to provide theJdbcDataSource
for the EPSG database to JNDI.- Author:
- Guy
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
GISUtils.EpsgDatabasePath
Contains a single static flag.
-
Constructor Summary
Constructors Constructor Description GISUtils()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static BoundingBox
constrainBoundingBox(BoundingBox bbox)
Constrains a lat-lon bounding box to have all longitude values in the range (-180:180]static double
constrainLongitude180(double value)
Returns a longitude value in degrees that is equal to the given value but in the range (-180:180]static double
constrainLongitude360(double value)
Returns a longitude value in degrees that is equal to the given value but in the range [0:360)static boolean
crsMatch(org.opengis.referencing.crs.CoordinateReferenceSystem sourceCrs, org.opengis.referencing.crs.CoordinateReferenceSystem targetCrs)
Tests whether 2CoordinateReferenceSystem
s are equivalentstatic org.opengis.referencing.crs.CoordinateReferenceSystem
defaultGeographicCRS()
Returns the default Lon-Lat geographic CRS.static BoundingBox
getBoundingBox(List<HorizontalPosition> positions)
Calculates theBoundingBox
of a set ofHorizontalPosition
s.static BoundingBox
getBoundingBoxOfBoxes(List<BoundingBox> bboxes)
Calculates theBoundingBox
of a set ofBoundingBox
es - i.e.static Double
getClosestElevationTo(Double targetZ, VerticalDomain zDomain)
Returns the closest elevation within a vertical domain to the given elevation.static Double
getClosestElevationToSurface(VerticalDomain vDomain)
Returns the closest elevation to the surface of the givenVerticalDomain
static org.joda.time.DateTime
getClosestTimeTo(org.joda.time.DateTime targetTime, TemporalDomain tDomain)
Returns the closest time within a temporal domain to the given time.static org.joda.time.DateTime
getClosestToCurrentTime(TemporalDomain tDomain)
Returns the closest time to the current time from a list of valuesstatic org.opengis.referencing.crs.CoordinateReferenceSystem
getCrs(String crsCode)
Finds aCoordinateReferenceSystem
with the given code, forcing longitude-first axis order.static double
getDistSquared(HorizontalPosition pos1, HorizontalPosition pos2)
Performs Pythagoras on two distances to calculate the distance squared.static int
getIndexOfClosestElevationTo(Double target, VerticalAxis zAxis)
static int
getIndexOfClosestTimeTo(org.joda.time.DateTime targetTime, TimeAxis timeAxis)
static HorizontalDomain
getIntersectionOfHorizontalDomains(HorizontalDomain... domains)
Gets the intersection of a number ofHorizontalDomain
sstatic TemporalDomain
getIntersectionOfTemporalDomains(TemporalDomain... domains)
Gets the intersection of a number ofTemporalDomain
sstatic VerticalDomain
getIntersectionOfVerticalDomains(VerticalDomain... domains)
Gets the intersection of a number ofVerticalDomain
sstatic BoundingBox
getLargeBoundingBox(BoundingBox bbox, double percentageIncrease)
Increases the size of aBoundingBox
by a given factorstatic double
getNearestEquivalentLongitude(double target, double longitude)
Given a target longitude and a longitude, this returns the longitude value which is nearest to the target, taking wrapping into accountstatic double
getNextEquivalentLongitude(double reference, double target)
Finds the next longitude which is greater than the reference longitude and equivalent to the target longitudeObject
getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?,?> environment)
static List<HorizontalPosition>
getOptimalTransectPoints(HorizontalGrid hGrid, LineString transect)
Gets a HorizontalDomain that contains (near) the minimum necessary number of points to sample a layer's source grid of data.static boolean
isDefaultGeographicCRS(org.opengis.referencing.crs.CoordinateReferenceSystem coordinateReferenceSystem)
Tests if a coordinate reference system is equivalent to the default geographic CRS.static boolean
isLatitudeUnits(String units)
static boolean
isLongitudeUnits(String units)
static boolean
isPressureUnits(String units)
static boolean
isTemporalDomainTimeAxis(TemporalDomain domain)
Tests whether aTemporalDomain
is discrete.static boolean
isVerticalDomainVerticalAxis(VerticalDomain domain)
Tests whether aVerticalDomain
is discrete.static boolean
isWgs84LonLat(org.opengis.referencing.crs.CoordinateReferenceSystem coordinateReferenceSystem)
Tests if a coordinate reference system is equivalent to WGS84 Lon-Latstatic TimeAxis
limitTAxis(TimeAxis axis, Extent<org.joda.time.DateTime> limits)
Limits a t-axis to include a range as tightly as possiblestatic VerticalAxis
limitZAxis(VerticalAxis axis, Extent<Double> limits)
Limits a z-axis to include a range as tightly as possiblestatic BoundingBox
parseBbox(String bboxStr, boolean xFirst, String crs)
Converts a string of the form "a1,b1,a2,b2" into aBoundingBox
static void
releaseEpsgDatabase()
static org.opengis.metadata.extent.GeographicBoundingBox
toGeographicBoundingBox(BoundingBox bbox)
Converts aBoundingBox
into aGeographicBoundingBox
(i.e.static BoundingBox
toWGS84BoundingBox(BoundingBox bbox)
Converts aBoundingBox
into aBoundingBox
using thedefaultGeographicCRS()
This method is not guaranteed to be exact.static HorizontalPosition
transformPosition(HorizontalPosition pos, org.opengis.referencing.crs.CoordinateReferenceSystem targetCrs)
Transforms the given HorizontalPosition to a new position in the given coordinate reference system.static Double
transformWgs84Heading(Number heading, HorizontalPosition position)
Transforms the given lat-lon heading to a differentCoordinateReferenceSystem
-
-
-
Field Detail
-
RAD2DEG
public static final double RAD2DEG
- See Also:
- Constant Field Values
-
DEG2RAD
public static final double DEG2RAD
- See Also:
- Constant Field Values
-
-
Method Detail
-
defaultGeographicCRS
public static org.opengis.referencing.crs.CoordinateReferenceSystem defaultGeographicCRS()
Returns the default Lon-Lat geographic CRS. This method guarantees that the returned CRS complies to the following conditions:- is geographic
- has axes in longitude, latitude order
- has longitude in degrees increasing toward East
- has latitude in degrees increasing toward North
- use the Greenwich prime meridian.
CommonCRS.defaultGeographic()
, which itself delegates to a geographic CRS based on the WGS84 datum. However the default may change in future versions, for example using a spherical CRS instead of WGS84.- Returns:
- the default geographic CRS with Lon-Lat axes in degrees.
-
isDefaultGeographicCRS
public static boolean isDefaultGeographicCRS(org.opengis.referencing.crs.CoordinateReferenceSystem coordinateReferenceSystem)
Tests if a coordinate reference system is equivalent to the default geographic CRS.- Parameters:
coordinateReferenceSystem
- TheCoordinateReferenceSystem
to test- Returns:
true
if the suppliedCoordinateReferenceSystem
is equivalent todefaultGeographicCRS()
-
isWgs84LonLat
public static boolean isWgs84LonLat(org.opengis.referencing.crs.CoordinateReferenceSystem coordinateReferenceSystem)
Tests if a coordinate reference system is equivalent to WGS84 Lon-Lat- Parameters:
coordinateReferenceSystem
- TheCoordinateReferenceSystem
to test- Returns:
true
if the suppliedCoordinateReferenceSystem
is equivalent to WGS84
-
getNextEquivalentLongitude
public static double getNextEquivalentLongitude(double reference, double target)
Finds the next longitude which is greater than the reference longitude and equivalent to the target longitude- Parameters:
reference
- The reference longitudetarget
- The target longitude- Returns:
- A longitude which is equivalent to the target and greater than the reference
-
constrainLongitude180
public static double constrainLongitude180(double value)
Returns a longitude value in degrees that is equal to the given value but in the range (-180:180]
-
constrainLongitude360
public static double constrainLongitude360(double value)
Returns a longitude value in degrees that is equal to the given value but in the range [0:360)
-
getNearestEquivalentLongitude
public static double getNearestEquivalentLongitude(double target, double longitude)
Given a target longitude and a longitude, this returns the longitude value which is nearest to the target, taking wrapping into account- Parameters:
target
- The longitude which we are aiming to be nearest tolongitude
- The longitude which we want to be nearest to the target- Returns:
- A longitude value which is equivalent to
longitude
-
constrainBoundingBox
public static BoundingBox constrainBoundingBox(BoundingBox bbox)
Constrains a lat-lon bounding box to have all longitude values in the range (-180:180]- Parameters:
bbox
- TheBoundingBox
to constrain- Returns:
- The constrained
BoundingBox
. If theBoundingBox
crosses the date line, aBoundingBox
which spans the entire range (-180:180] will be returned
-
transformPosition
public static HorizontalPosition transformPosition(HorizontalPosition pos, org.opengis.referencing.crs.CoordinateReferenceSystem targetCrs)
Transforms the given HorizontalPosition to a new position in the given coordinate reference system.- Parameters:
pos
- The position to translate.targetCrs
- The CRS to translate into- Returns:
- a new position in the given CRS, or the same position if the new
CRS is the same as the point's CRS. The returned point's CRS will
be set to
targetCrs
. If the CRS of the position is null, the CRS will simply be set to the targetCrs. - Throws:
NullPointerException
- iftargetCrs
is null.
-
transformWgs84Heading
public static Double transformWgs84Heading(Number heading, HorizontalPosition position)
Transforms the given lat-lon heading to a differentCoordinateReferenceSystem
- Parameters:
heading
- The heading in degreesposition
- TheHorizontalPosition
at which to transform the heading. TheCoordinateReferenceSystem
returned byHorizontalPosition.getCoordinateReferenceSystem()
will be theCoordinateReferenceSystem
in which the heading is valid.- Returns:
- The heading, in degrees clockwise from "upwards" (i.e. y-positive in the target CRS)
-
crsMatch
public static boolean crsMatch(org.opengis.referencing.crs.CoordinateReferenceSystem sourceCrs, org.opengis.referencing.crs.CoordinateReferenceSystem targetCrs)
Tests whether 2CoordinateReferenceSystem
s are equivalent- Parameters:
sourceCrs
- The firstCoordinateReferenceSystem
to testtargetCrs
- The secondCoordinateReferenceSystem
to test
-
getCrs
public static org.opengis.referencing.crs.CoordinateReferenceSystem getCrs(String crsCode) throws InvalidCrsException
Finds aCoordinateReferenceSystem
with the given code, forcing longitude-first axis order.- Parameters:
crsCode
- The code for the CRS- Returns:
- a coordinate reference system with the longitude axis first
- Throws:
InvalidCrsException
- if a CRS matching the code cannot be foundNullPointerException
- ifcrsCode
is null
-
parseBbox
public static BoundingBox parseBbox(String bboxStr, boolean xFirst, String crs) throws EdalException
Converts a string of the form "a1,b1,a2,b2" into aBoundingBox
- Parameters:
bboxStr
- A string of the form "a1,b1,a2,b2". If xFirst istrue
, then a1, a2 represent the x-coordinates and b1,b2 represent the y-coordinates, otherwise it is the other way aroundxFirst
- Whether the x-coordinates are first or second in the listcrs
- A string representing theCoordinateReferenceSystem
of theBoundingBox
- Throws:
EdalException
- if the format of the bounding box is invalid
-
isTemporalDomainTimeAxis
public static boolean isTemporalDomainTimeAxis(TemporalDomain domain)
Tests whether aTemporalDomain
is discrete. Used when generating Capabilities document in WMS
-
isVerticalDomainVerticalAxis
public static boolean isVerticalDomainVerticalAxis(VerticalDomain domain)
Tests whether aVerticalDomain
is discrete. Used when generating Capabilities document in WMS
-
getClosestToCurrentTime
public static org.joda.time.DateTime getClosestToCurrentTime(TemporalDomain tDomain)
Returns the closest time to the current time from a list of values- Parameters:
tDomain
- The list of times to check- Returns:
- The closest from the list to the current time.
-
getClosestTimeTo
public static org.joda.time.DateTime getClosestTimeTo(org.joda.time.DateTime targetTime, TemporalDomain tDomain)
Returns the closest time within a temporal domain to the given time.- Parameters:
targetTime
- The target timetDomain
- TheTemporalDomain
to check- Returns:
- Either the closest time within that axis, or the closest to the
current time if the target is
null
, ornull
if the list of times isnull
-
getIndexOfClosestTimeTo
public static int getIndexOfClosestTimeTo(org.joda.time.DateTime targetTime, TimeAxis timeAxis)
-
getClosestElevationToSurface
public static Double getClosestElevationToSurface(VerticalDomain vDomain)
Returns the closest elevation to the surface of the givenVerticalDomain
- Parameters:
vDomain
- TheVerticalDomain
to test- Returns:
- The uppermost elevation, or null if no
VerticalDomain
is provided
-
getClosestElevationTo
public static Double getClosestElevationTo(Double targetZ, VerticalDomain zDomain)
Returns the closest elevation within a vertical domain to the given elevation.- Parameters:
targetZ
- The target elevationzDomain
- TheVerticalDomain
to check- Returns:
- Either the closest elevation within that axis, or the closest to
the surface if the target is
null
, ornull
if theVerticalDomain
isnull
-
getIndexOfClosestElevationTo
public static int getIndexOfClosestElevationTo(Double target, VerticalAxis zAxis)
-
getOptimalTransectPoints
public static List<HorizontalPosition> getOptimalTransectPoints(HorizontalGrid hGrid, LineString transect)
Gets a HorizontalDomain that contains (near) the minimum necessary number of points to sample a layer's source grid of data. That is to say, creating a HorizontalDomain at higher resolution would not result in sampling significantly more points in the layer's source grid.- Parameters:
hGrid
- TheHorizontalGrid
to find transect point ontransect
- The transect as specified in the request- Returns:
- a HorizontalDomain that contains (near) the minimum necessary number of points to sample a layer's source grid of data.
-
toWGS84BoundingBox
public static BoundingBox toWGS84BoundingBox(BoundingBox bbox)
Converts aBoundingBox
into aBoundingBox
using thedefaultGeographicCRS()
This method is not guaranteed to be exact. Its aim is to choose bounding boxes which contain all of the data - there is no requirement that the bounding box is a tight fit.- Parameters:
bbox
- The bounding box- Returns:
- A
BoundingBox
in thedefaultGeographicCRS()
CRS which contains the suppliedBoundingBox
-
toGeographicBoundingBox
public static org.opengis.metadata.extent.GeographicBoundingBox toGeographicBoundingBox(BoundingBox bbox)
Converts aBoundingBox
into aGeographicBoundingBox
(i.e. one which is in lat/lon WGS84). This method is not guaranteed to be exact. Its aim is to choose bounding boxes which contain all of the data - there is no requirement that the bounding box is a tight fit.- Parameters:
bbox
- The bounding box- Returns:
- A
GeographicBoundingBox
which contains the suppliedBoundingBox
-
getLargeBoundingBox
public static BoundingBox getLargeBoundingBox(BoundingBox bbox, double percentageIncrease)
Increases the size of aBoundingBox
by a given factor- Parameters:
bbox
- TheBoundingBox
to increase the size ofpercentageIncrease
- The percentage increase- Returns:
- A larger
BoundingBox
with the same centre
-
getBoundingBox
public static BoundingBox getBoundingBox(List<HorizontalPosition> positions)
Calculates theBoundingBox
of a set ofHorizontalPosition
s.- Parameters:
positions
- aList
ofHorizontalPosition
s, which must all share the same CRS- Returns:
- The minimum bounding rectangle of the supplied positions
- Throws:
MismatchedCrsException
- if not all positions share the same CRS
-
getBoundingBoxOfBoxes
public static BoundingBox getBoundingBoxOfBoxes(List<BoundingBox> bboxes)
Calculates theBoundingBox
of a set ofBoundingBox
es - i.e. the minimumBoundingBox
which will encompass them all- Parameters:
bboxes
- aList
ofBoundingBox
es, which must all share the same CRS- Returns:
- The minimum bounding rectangle of the supplied
BoundingBox
es - Throws:
MismatchedCrsException
- if not all positions share the same CRS
-
getIntersectionOfHorizontalDomains
public static HorizontalDomain getIntersectionOfHorizontalDomains(HorizontalDomain... domains)
Gets the intersection of a number ofHorizontalDomain
s- Parameters:
domains
- TheHorizontalDomain
s to find a intersection of- Returns:
- A new
HorizontalDomain
whoseBoundingBox
represents the area where valid values can be found in all the suppliedHorizontalDomain
s. TheCoordinateReferenceSystem
of the returnedHorizontalDomain
will be the same as the suppliedHorizontalDomain
s if they match, otherwise it will be WGS84. If all of the suppliedHorizontalDomain
s have anull
CRS, they are assumed to have the same (undefined) CRS. If there is a mixture ofnull
and non-null
CRSes, there is no intersection.
-
getIntersectionOfVerticalDomains
public static VerticalDomain getIntersectionOfVerticalDomains(VerticalDomain... domains)
Gets the intersection of a number ofVerticalDomain
s- Parameters:
domains
- TheVerticalDomain
s to find a intersection of. They must all share the sameVerticalCrs
- Returns:
- A new
VerticalDomain
whose extent represents the range where valid values can be found in all the suppliedVerticalDomain
s
-
getIntersectionOfTemporalDomains
public static TemporalDomain getIntersectionOfTemporalDomains(TemporalDomain... domains)
Gets the intersection of a number ofTemporalDomain
s- Parameters:
domains
- TheTemporalDomain
s to find a intersection of- Returns:
- A new
TemporalDomain
whose extent represents the range where valid values can be found in all the suppliedTemporalDomain
s
-
getDistSquared
public static double getDistSquared(HorizontalPosition pos1, HorizontalPosition pos2)
Performs Pythagoras on two distances to calculate the distance squared. Useful for sorting lists according to distance from a point. The result shouldn't be used for anything critical, since two results may not accurately reflect the true distance (e.g. two points near the pole may incorrectly report a smaller distance apart than two near the equator). No check that the positions have the same CRS is performed (for speed).- Parameters:
pos1
- The first positionpos2
- The second position- Returns:
- A number related to how far apart the positions are, or
Double.MAX_VALUE
if either isnull
-
limitZAxis
public static VerticalAxis limitZAxis(VerticalAxis axis, Extent<Double> limits)
Limits a z-axis to include a range as tightly as possible- Parameters:
axis
- The axis to limitlimits
- The range to limit to- Returns:
- A new
VerticalAxis
which will extend by at most one point over each of the bounds provided by limits, or the original axis if limits isnull
-
limitTAxis
public static TimeAxis limitTAxis(TimeAxis axis, Extent<org.joda.time.DateTime> limits)
Limits a t-axis to include a range as tightly as possible- Parameters:
axis
- The axis to limitlimits
- The range to limit to- Returns:
- A new
TimeAxis
which will extend by at most one point over each of the bounds provided by limits, or the original axis if limits isnull
-
getObjectInstance
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?,?> environment) throws Exception
- Specified by:
getObjectInstance
in interfaceObjectFactory
- Throws:
Exception
-
releaseEpsgDatabase
public static void releaseEpsgDatabase()
-
isPressureUnits
public static boolean isPressureUnits(String units)
-
isLatitudeUnits
public static boolean isLatitudeUnits(String units)
-
isLongitudeUnits
public static boolean isLongitudeUnits(String units)
-
-