| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.sis.referencing.operation.provider; |
| |
| import jakarta.xml.bind.annotation.XmlTransient; |
| import org.opengis.util.FactoryException; |
| import org.opengis.parameter.ParameterDescriptor; |
| import org.opengis.parameter.ParameterDescriptorGroup; |
| import org.opengis.referencing.cs.EllipsoidalCS; |
| import org.opengis.referencing.operation.Conversion; |
| import org.opengis.referencing.operation.MathTransform; |
| import org.apache.sis.referencing.operation.transform.PoleRotation; |
| import org.apache.sis.metadata.iso.citation.Citations; |
| import org.apache.sis.parameter.ParameterBuilder; |
| import org.apache.sis.parameter.Parameters; |
| import org.apache.sis.measure.Longitude; |
| import org.apache.sis.measure.Latitude; |
| import org.apache.sis.measure.Units; |
| |
| |
| /** |
| * The provider for the WMO <cite>Rotated Latitude/Longitude</cite> coordinate operation. |
| * This is defined by the World Meteorological Organization (WMO) in GRIB2 template 3.1. |
| * The 180° rotated meridian runs through both the geographical and the rotated South pole. |
| * |
| * <h2>Comparison with UCAR library</h2> |
| * This is consistent with {@link ucar.unidata.geoloc.projection.RotatedLatLon} |
| * in UCAR netCDF library version 5.5.2. |
| * |
| * @author Martin Desruisseaux (Geomatys) |
| * |
| * @see NorthPoleRotation |
| */ |
| @XmlTransient |
| public final class SouthPoleRotation extends AbstractProvider { |
| /** |
| * For cross-version compatibility. |
| */ |
| private static final long serialVersionUID = -5970630604222205521L; |
| |
| /** |
| * The operation parameter descriptor for the <cite>grid south pole latitude</cite> parameter value. |
| * This is the geographic latitude (usually in degrees) of the southern pole of the coordinate system. |
| * The symbol used in GRIB2 template 3.1 is θ<sub>p</sub>. |
| * |
| * <!-- Generated by ParameterNameTableGenerator --> |
| * <table class="sis"> |
| * <caption>Parameter names</caption> |
| * <tr><td> SIS: </td><td> Latitude of rotated pole </td></tr> |
| * <tr><td> NetCDF: </td><td> grid_south_pole_latitude </td></tr> |
| * </table> |
| * <b>Notes:</b> |
| * <ul> |
| * <li>No default value</li> |
| * </ul> |
| */ |
| static final ParameterDescriptor<Double> POLE_LATITUDE; |
| |
| /** |
| * The operation parameter descriptor for the <cite>grid south pole longitude</cite> parameter value. |
| * This is the geographic longitude (usually in degrees) of the southern pole of the coordinate system. |
| * The symbol used in GRIB2 template 3.1 is λ<sub>p</sub>. |
| * |
| * <!-- Generated by ParameterNameTableGenerator --> |
| * <table class="sis"> |
| * <caption>Parameter names</caption> |
| * <tr><td> SIS: </td><td> Longitude of rotated pole </td></tr> |
| * <tr><td> NetCDF: </td><td> grid_south_pole_longitude </td></tr> |
| * </table> |
| * <b>Notes:</b> |
| * <ul> |
| * <li>No default value</li> |
| * </ul> |
| */ |
| static final ParameterDescriptor<Double> POLE_LONGITUDE; |
| |
| /** |
| * The operation parameter descriptor for the <cite>grid_south_pole_angle</cite> parameter value (optional). |
| * This is the angle of rotation about the new polar axis (measured clockwise when looking from the southern |
| * to the northern pole) of the coordinate system, assuming the new axis to have been obtained by first |
| * rotating the sphere through λ<sub>p</sub> about the geographic polar axis, and then rotating through |
| * (90° + θ<sub>p</sub>) degrees so that the southern pole moved along the (previously rotated) Greenwich meridian. |
| * |
| * <!-- Generated by ParameterNameTableGenerator --> |
| * <table class="sis"> |
| * <caption>Parameter names</caption> |
| * <tr><td> SIS: </td><td> Axis rotation </td></tr> |
| * <tr><td> NetCDF: </td><td> grid_south_pole_angle </td></tr> |
| * </table> |
| * <b>Notes:</b> |
| * <ul> |
| * <li>Value domain: [-180.0 … 180.0]°</li> |
| * <li>Optional</li> |
| * </ul> |
| */ |
| static final ParameterDescriptor<Double> AXIS_ANGLE; |
| |
| /** |
| * The group of all parameters expected by this coordinate operation. |
| */ |
| public static final ParameterDescriptorGroup PARAMETERS; |
| static { |
| final ParameterBuilder builder = new ParameterBuilder().setCodeSpace(Citations.NETCDF, "NetCDF").setRequired(true); |
| |
| POLE_LATITUDE = builder |
| .addName(Citations.SIS, "Latitude of rotated pole") |
| .addName("grid_south_pole_latitude") |
| .createBounded(Latitude.MIN_VALUE, Latitude.MAX_VALUE, Double.NaN, Units.DEGREE); |
| |
| POLE_LONGITUDE = builder |
| .addName(Citations.SIS, "Longitude of rotated pole") |
| .addName("grid_south_pole_longitude") |
| .createBounded(Longitude.MIN_VALUE, Longitude.MAX_VALUE, Double.NaN, Units.DEGREE); |
| |
| AXIS_ANGLE = builder.setRequired(false) |
| .addName(Citations.SIS, "Axis rotation") |
| .addName("grid_south_pole_angle") |
| .createBounded(Longitude.MIN_VALUE, Longitude.MAX_VALUE, 0, Units.DEGREE); |
| |
| PARAMETERS = builder.setRequired(true) |
| .addName(Citations.SIS, "South pole rotation") |
| .addName(Citations.WMO, "Rotated Latitude/longitude") |
| .addName("rotated_latlon_grib") |
| .createGroup(POLE_LATITUDE, // Note: `PoleRotation` implementation depends on this parameter order. |
| POLE_LONGITUDE, |
| AXIS_ANGLE); |
| } |
| |
| /** |
| * Constructs a new provider. |
| */ |
| public SouthPoleRotation() { |
| super(Conversion.class, PARAMETERS, |
| EllipsoidalCS.class, false, |
| EllipsoidalCS.class, false, |
| (byte) 2); |
| } |
| |
| /** |
| * Creates a coordinate operation from the specified group of parameter values. |
| * |
| * @param context the parameter values together with its context. |
| * @return the coordinate operation created from the given parameter values. |
| * @throws FactoryException if the coordinate operation cannot be created. |
| */ |
| @Override |
| public MathTransform createMathTransform(final Context context) throws FactoryException { |
| final Parameters p = Parameters.castOrWrap(context.getCompletedParameters()); |
| return PoleRotation.rotateSouthPole(context.getFactory(), |
| p.getValue(POLE_LATITUDE), |
| p.getValue(POLE_LONGITUDE), |
| p.getValue(AXIS_ANGLE)); |
| } |
| } |