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 implementsObjectFactoryso that it can be used to provide theJdbcDataSourcefor the EPSG database to JNDI.- Author:
- Guy
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classGISUtils.EpsgDatabasePathContains 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 BoundingBoxconstrainBoundingBox(BoundingBox bbox)Constrains a lat-lon bounding box to have all longitude values in the range (-180:180]static doubleconstrainLongitude180(double value)Returns a longitude value in degrees that is equal to the given value but in the range (-180:180]static doubleconstrainLongitude360(double value)Returns a longitude value in degrees that is equal to the given value but in the range [0:360)static booleancrsMatch(org.opengis.referencing.crs.CoordinateReferenceSystem sourceCrs, org.opengis.referencing.crs.CoordinateReferenceSystem targetCrs)Tests whether 2CoordinateReferenceSystems are equivalentstatic org.opengis.referencing.crs.CoordinateReferenceSystemdefaultGeographicCRS()Returns the default Lon-Lat geographic CRS.static BoundingBoxgetBoundingBox(List<HorizontalPosition> positions)Calculates theBoundingBoxof a set ofHorizontalPositions.static BoundingBoxgetBoundingBoxOfBoxes(List<BoundingBox> bboxes)Calculates theBoundingBoxof a set ofBoundingBoxes - i.e.static DoublegetClosestElevationTo(Double targetZ, VerticalDomain zDomain)Returns the closest elevation within a vertical domain to the given elevation.static DoublegetClosestElevationToSurface(VerticalDomain vDomain)Returns the closest elevation to the surface of the givenVerticalDomainstatic org.joda.time.DateTimegetClosestTimeTo(org.joda.time.DateTime targetTime, TemporalDomain tDomain)Returns the closest time within a temporal domain to the given time.static org.joda.time.DateTimegetClosestToCurrentTime(TemporalDomain tDomain)Returns the closest time to the current time from a list of valuesstatic org.opengis.referencing.crs.CoordinateReferenceSystemgetCrs(String crsCode)Finds aCoordinateReferenceSystemwith the given code, forcing longitude-first axis order.static doublegetDistSquared(HorizontalPosition pos1, HorizontalPosition pos2)Performs Pythagoras on two distances to calculate the distance squared.static intgetIndexOfClosestElevationTo(Double target, VerticalAxis zAxis)static intgetIndexOfClosestTimeTo(org.joda.time.DateTime targetTime, TimeAxis timeAxis)static HorizontalDomaingetIntersectionOfHorizontalDomains(HorizontalDomain... domains)Gets the intersection of a number ofHorizontalDomainsstatic TemporalDomaingetIntersectionOfTemporalDomains(TemporalDomain... domains)Gets the intersection of a number ofTemporalDomainsstatic VerticalDomaingetIntersectionOfVerticalDomains(VerticalDomain... domains)Gets the intersection of a number ofVerticalDomainsstatic BoundingBoxgetLargeBoundingBox(BoundingBox bbox, double percentageIncrease)Increases the size of aBoundingBoxby a given factorstatic doublegetNearestEquivalentLongitude(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 doublegetNextEquivalentLongitude(double reference, double target)Finds the next longitude which is greater than the reference longitude and equivalent to the target longitudeObjectgetObjectInstance(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 booleanisDefaultGeographicCRS(org.opengis.referencing.crs.CoordinateReferenceSystem coordinateReferenceSystem)Tests if a coordinate reference system is equivalent to the default geographic CRS.static booleanisLatitudeUnits(String units)static booleanisLongitudeUnits(String units)static booleanisPressureUnits(String units)static booleanisTemporalDomainTimeAxis(TemporalDomain domain)Tests whether aTemporalDomainis discrete.static booleanisVerticalDomainVerticalAxis(VerticalDomain domain)Tests whether aVerticalDomainis discrete.static booleanisWgs84LonLat(org.opengis.referencing.crs.CoordinateReferenceSystem coordinateReferenceSystem)Tests if a coordinate reference system is equivalent to WGS84 Lon-Latstatic TimeAxislimitTAxis(TimeAxis axis, Extent<org.joda.time.DateTime> limits)Limits a t-axis to include a range as tightly as possiblestatic VerticalAxislimitZAxis(VerticalAxis axis, Extent<Double> limits)Limits a z-axis to include a range as tightly as possiblestatic BoundingBoxparseBbox(String bboxStr, boolean xFirst, String crs)Converts a string of the form "a1,b1,a2,b2" into aBoundingBoxstatic voidreleaseEpsgDatabase()static org.opengis.metadata.extent.GeographicBoundingBoxtoGeographicBoundingBox(BoundingBox bbox)Converts aBoundingBoxinto aGeographicBoundingBox(i.e.static BoundingBoxtoWGS84BoundingBox(BoundingBox bbox)Converts aBoundingBoxinto aBoundingBoxusing thedefaultGeographicCRS()This method is not guaranteed to be exact.static HorizontalPositiontransformPosition(HorizontalPosition pos, org.opengis.referencing.crs.CoordinateReferenceSystem targetCrs)Transforms the given HorizontalPosition to a new position in the given coordinate reference system.static DoubletransformWgs84Heading(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- TheCoordinateReferenceSystemto test- Returns:
trueif the suppliedCoordinateReferenceSystemis 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- TheCoordinateReferenceSystemto test- Returns:
trueif the suppliedCoordinateReferenceSystemis 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- TheBoundingBoxto constrain- Returns:
- The constrained
BoundingBox. If theBoundingBoxcrosses the date line, aBoundingBoxwhich 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- iftargetCrsis 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- TheHorizontalPositionat which to transform the heading. TheCoordinateReferenceSystemreturned byHorizontalPosition.getCoordinateReferenceSystem()will be theCoordinateReferenceSystemin 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 2CoordinateReferenceSystems are equivalent- Parameters:
sourceCrs- The firstCoordinateReferenceSystemto testtargetCrs- The secondCoordinateReferenceSystemto test
-
getCrs
public static org.opengis.referencing.crs.CoordinateReferenceSystem getCrs(String crsCode) throws InvalidCrsException
Finds aCoordinateReferenceSystemwith 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- ifcrsCodeis 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 theCoordinateReferenceSystemof theBoundingBox- Throws:
EdalException- if the format of the bounding box is invalid
-
isTemporalDomainTimeAxis
public static boolean isTemporalDomainTimeAxis(TemporalDomain domain)
Tests whether aTemporalDomainis discrete. Used when generating Capabilities document in WMS
-
isVerticalDomainVerticalAxis
public static boolean isVerticalDomainVerticalAxis(VerticalDomain domain)
Tests whether aVerticalDomainis 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- TheTemporalDomainto check- Returns:
- Either the closest time within that axis, or the closest to the
current time if the target is
null, ornullif 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- TheVerticalDomainto test- Returns:
- The uppermost elevation, or null if no
VerticalDomainis 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- TheVerticalDomainto check- Returns:
- Either the closest elevation within that axis, or the closest to
the surface if the target is
null, ornullif theVerticalDomainisnull
-
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- TheHorizontalGridto 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 aBoundingBoxinto aBoundingBoxusing 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
BoundingBoxin thedefaultGeographicCRS()CRS which contains the suppliedBoundingBox
-
toGeographicBoundingBox
public static org.opengis.metadata.extent.GeographicBoundingBox toGeographicBoundingBox(BoundingBox bbox)
Converts aBoundingBoxinto 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
GeographicBoundingBoxwhich contains the suppliedBoundingBox
-
getLargeBoundingBox
public static BoundingBox getLargeBoundingBox(BoundingBox bbox, double percentageIncrease)
Increases the size of aBoundingBoxby a given factor- Parameters:
bbox- TheBoundingBoxto increase the size ofpercentageIncrease- The percentage increase- Returns:
- A larger
BoundingBoxwith the same centre
-
getBoundingBox
public static BoundingBox getBoundingBox(List<HorizontalPosition> positions)
Calculates theBoundingBoxof a set ofHorizontalPositions.- Parameters:
positions- aListofHorizontalPositions, 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 theBoundingBoxof a set ofBoundingBoxes - i.e. the minimumBoundingBoxwhich will encompass them all- Parameters:
bboxes- aListofBoundingBoxes, which must all share the same CRS- Returns:
- The minimum bounding rectangle of the supplied
BoundingBoxes - Throws:
MismatchedCrsException- if not all positions share the same CRS
-
getIntersectionOfHorizontalDomains
public static HorizontalDomain getIntersectionOfHorizontalDomains(HorizontalDomain... domains)
Gets the intersection of a number ofHorizontalDomains- Parameters:
domains- TheHorizontalDomains to find a intersection of- Returns:
- A new
HorizontalDomainwhoseBoundingBoxrepresents the area where valid values can be found in all the suppliedHorizontalDomains. TheCoordinateReferenceSystemof the returnedHorizontalDomainwill be the same as the suppliedHorizontalDomains if they match, otherwise it will be WGS84. If all of the suppliedHorizontalDomains have anullCRS, they are assumed to have the same (undefined) CRS. If there is a mixture ofnulland non-nullCRSes, there is no intersection.
-
getIntersectionOfVerticalDomains
public static VerticalDomain getIntersectionOfVerticalDomains(VerticalDomain... domains)
Gets the intersection of a number ofVerticalDomains- Parameters:
domains- TheVerticalDomains to find a intersection of. They must all share the sameVerticalCrs- Returns:
- A new
VerticalDomainwhose extent represents the range where valid values can be found in all the suppliedVerticalDomains
-
getIntersectionOfTemporalDomains
public static TemporalDomain getIntersectionOfTemporalDomains(TemporalDomain... domains)
Gets the intersection of a number ofTemporalDomains- Parameters:
domains- TheTemporalDomains to find a intersection of- Returns:
- A new
TemporalDomainwhose extent represents the range where valid values can be found in all the suppliedTemporalDomains
-
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_VALUEif 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
VerticalAxiswhich 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
TimeAxiswhich 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:
getObjectInstancein 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)
-
-