Search in sources :

Example 6 with ParameterDescriptor

use of org.opengis.parameter.ParameterDescriptor in project sis by apache.

the class CC_OperationParameterGroup method merge.

/**
 * Invoked by {@link DefaultParameterDescriptorGroup#setDescriptors(GeneralParameterDescriptor[])}
 * for merging into a single set the descriptors which are repeated twice in a GML document.
 *
 * <p>The {@code descriptors} argument gives the descriptors listed explicitely inside a
 * {@code <gml:OperationParameterGroup>} or {@code <gml:OperationMethod>} element. Those
 * descriptors are said "incomplete" (from SIS point of view) because they are missing the
 * {@link ParameterDescriptor#getValueClass()} property, which does not exist in GML but
 * is mandatory for us. However an exception to this "incompleteness" happen when SIS has
 * been able to match the {@code <gml:OperationMethod>} parent to one of the pre-defined
 * operations in the {@link org.apache.sis.internal.referencing.provider} package.</p>
 *
 * <p>The {@code fromValues} argument gives the descriptors declared in each {@code <gml:ParameterValue>}
 * instances of a {@code <gml:ParameterValueGroup>} or {@code <gml:AbstractSingleOperation>} element.
 * Contrarily to the {@code descriptors} argument, the {@code fromValues} instances should have non-null
 * {@link ParameterDescriptor#getValueClass()} property inferred by SIS from the parameter value.</p>
 *
 * <p>So the preferred descriptors from more complete to less complete are:</p>
 * <ol>
 *   <li>{@code descriptors} if and only if they contain pre-defined parameters inferred by SIS from the {@code <gml:OperationMethod>} name.</li>
 *   <li>{@code fromValues}, which contain the descriptors declared in the {@code <gml:ParameterValue>} instances.</li>
 *   <li>{@code descriptors}, which contain the descriptor listed in {@code <gml:OperationParameterGroup>} or {@code <gml:OperationMethod>}.</li>
 * </ol>
 *
 * <div class="note"><b>Note:</b>
 * this code is defined in this {@code CC_OperationParameterGroup} class instead than in the
 * {@link DefaultParameterDescriptorGroup} class in the hope to reduce the amount of code
 * processed by the JVM in the common case where JAXB (un)marshalling is not needed.</div>
 *
 * @param  descriptors   the descriptors declared in the {@code ParameterDescriptorGroup}.
 * @param  fromValues    the descriptors declared in the {@code ParameterValue} instances.
 *                       They are said "valid" because they contain the mandatory {@code valueClass} property.
 * @param  replacements  an {@code IdentityHashMap} where to store the replacements that the caller needs to
 *                       apply in the {@code GeneralParameterValue} instances.
 * @return a sequence containing the merged set of parameter descriptors.
 *
 * @see <a href="http://issues.apache.org/jira/browse/SIS-290">SIS-290</a>
 */
public static GeneralParameterDescriptor[] merge(final List<GeneralParameterDescriptor> descriptors, final GeneralParameterDescriptor[] fromValues, final Map<GeneralParameterDescriptor, GeneralParameterDescriptor> replacements) {
    if (descriptors.isEmpty()) {
        return fromValues;
    }
    final Map<String, GeneralParameterDescriptor> union = new LinkedHashMap<>(Containers.hashMapCapacity(descriptors.size()));
    /*
         * Collect the descriptors declared explicitely in the ParameterDescriptorGroup. We should never have
         * two descriptors of the same name since the DefaultParameterDescriptorGroup constructor checked for
         * name ambiguity. If a name collision is nevertheless detected, this would mean that a descriptor's
         * name mutated.
         */
    for (final GeneralParameterDescriptor p : descriptors) {
        final String name = p.getName().getCode();
        if (union.put(name, p) != null) {
            throw new CorruptedObjectException(name);
        }
    }
    /*
         * Verify if any descriptors found in the ParameterValue instances could replace the descriptors in the group.
         * We give precedence to the descriptors having a non-null 'valueClass' property, which normally appear in the
         * 'fromValues' array.
         */
    for (final GeneralParameterDescriptor valueDescriptor : fromValues) {
        final String name = valueDescriptor.getName().getCode();
        GeneralParameterDescriptor complete = valueDescriptor;
        GeneralParameterDescriptor previous = union.put(name, complete);
        if (previous != null) {
            if (previous instanceof ParameterDescriptor<?>) {
                verifyEquivalence(name, complete instanceof ParameterDescriptor<?>);
                final Class<?> valueClass = ((ParameterDescriptor<?>) previous).getValueClass();
                if (valueClass != null) {
                    /*
                         * This may happen if the 'descriptors' argument contain the parameters of a pre-defined
                         * method from the 'org.apache.sis.internal.referencing.provider' package instead than a
                         * descriptor from the GML file.  In such case, presume that 'previous' is actually more
                         * complete than 'complete'.
                         *
                         * Note that 'r' should never be null unless JAXB unmarshalled the elements in reverse
                         * order (e.g. <gml:ParameterValue> before <gml:OperationMethod>). Since this behavior
                         * may depend on JAXB implementation, we are better to check for such case.
                         */
                    final Class<?> r = ((ParameterDescriptor<?>) complete).getValueClass();
                    if (r != null) {
                        verifyEquivalence(name, valueClass == r);
                    }
                    // Restore the previous value in the map and swap 'previous' with 'replacement'.
                    previous = union.put(name, complete = previous);
                }
            } else if (previous instanceof ParameterDescriptorGroup) {
                verifyEquivalence(name, complete instanceof ParameterDescriptorGroup);
            }
            /*
                 * Verify that the replacement contains at least all the information provided by the previous
                 * descriptor. The replacement is allowed to contain more information however.
                 */
            final GeneralParameterDescriptor replacement = CC_GeneralOperationParameter.merge(previous, complete);
            if (replacement != valueDescriptor) {
                union.put(name, replacement);
                if (replacements.put(valueDescriptor, replacement) != null) {
                    // Should never happen, unless the parameter name changed during execution of this loop.
                    throw new CorruptedObjectException(name);
                }
            }
        }
    }
    return union.values().toArray(new GeneralParameterDescriptor[union.size()]);
}
Also used : GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterDescriptor(org.opengis.parameter.ParameterDescriptor) DefaultParameterDescriptorGroup(org.apache.sis.parameter.DefaultParameterDescriptorGroup) ParameterDescriptorGroup(org.opengis.parameter.ParameterDescriptorGroup) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) CorruptedObjectException(org.apache.sis.util.CorruptedObjectException) LinkedHashMap(java.util.LinkedHashMap)

Example 7 with ParameterDescriptor

use of org.opengis.parameter.ParameterDescriptor in project sis by apache.

the class EPSGDataAccess method createOperationMethod.

/**
 * Creates description of the algorithm and parameters used to perform a coordinate operation.
 * An {@code OperationMethod} is a kind of metadata: it does not perform any coordinate operation
 * (e.g. map projection) by itself, but tells us what is needed in order to perform such operation.
 *
 * <div class="note"><b>Example:</b>
 * some EPSG codes for operation methods are:
 *
 * <table class="sis" summary="EPSG codes examples">
 *   <tr><th>Code</th> <th>Description</th></tr>
 *   <tr><td>9804</td> <td>Mercator (variant A)</td></tr>
 *   <tr><td>9802</td> <td>Lambert Conic Conformal (2SP)</td></tr>
 *   <tr><td>9810</td> <td>Polar Stereographic (variant A)</td></tr>
 *   <tr><td>9624</td> <td>Affine parametric transformation</td></tr>
 * </table></div>
 *
 * @param  code  value allocated by EPSG.
 * @return the operation method for the given code.
 * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
 * @throws FactoryException if the object creation failed for some other reason.
 */
@Override
public synchronized OperationMethod createOperationMethod(final String code) throws NoSuchAuthorityCodeException, FactoryException {
    ArgumentChecks.ensureNonNull("code", code);
    OperationMethod returnValue = null;
    try (ResultSet result = executeQuery("Coordinate_Operation Method", "COORD_OP_METHOD_CODE", "COORD_OP_METHOD_NAME", "SELECT COORD_OP_METHOD_CODE," + " COORD_OP_METHOD_NAME," + " REMARKS," + " DEPRECATED" + " FROM [Coordinate_Operation Method]" + " WHERE COORD_OP_METHOD_CODE = ?", code)) {
        while (result.next()) {
            final Integer epsg = getInteger(code, result, 1);
            final String name = getString(code, result, 2);
            final String remarks = getOptionalString(result, 3);
            final boolean deprecated = getOptionalBoolean(result, 4);
            final Integer[] dim = getDimensionsForMethod(epsg);
            final ParameterDescriptor<?>[] descriptors = createParameterDescriptors(epsg);
            Map<String, Object> properties = createProperties("Coordinate_Operation Method", name, epsg, remarks, deprecated);
            // We do not store the formula at this time, because the text is very verbose and rarely used.
            final OperationMethod method = new DefaultOperationMethod(properties, dim[0], dim[1], new DefaultParameterDescriptorGroup(properties, 1, 1, descriptors));
            returnValue = ensureSingleton(method, returnValue, code);
        }
    } catch (SQLException exception) {
        throw databaseFailure(OperationMethod.class, code, exception);
    }
    if (returnValue == null) {
        throw noSuchAuthorityCode(OperationMethod.class, code);
    }
    return returnValue;
}
Also used : SQLException(java.sql.SQLException) ParameterDescriptor(org.opengis.parameter.ParameterDescriptor) DefaultParameterDescriptor(org.apache.sis.parameter.DefaultParameterDescriptor) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) DefaultOperationMethod(org.apache.sis.referencing.operation.DefaultOperationMethod) DefaultParameterDescriptorGroup(org.apache.sis.parameter.DefaultParameterDescriptorGroup) ResultSet(java.sql.ResultSet) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) IdentifiedObject(org.opengis.referencing.IdentifiedObject) DefaultOperationMethod(org.apache.sis.referencing.operation.DefaultOperationMethod)

Example 8 with ParameterDescriptor

use of org.opengis.parameter.ParameterDescriptor in project sis by apache.

the class CC_OperationParameterGroupTest method create.

/**
 * Creates the parameter descriptors equivalent to the result of {@link #unmarshal()}
 * but with value class, units and default values.
 *
 * @param remarks Remarks to associate to the latitude parameter, or {@code null} if none.
 */
private static ParameterDescriptor<?>[] create(final String remarks) {
    final ParameterBuilder builder = new ParameterBuilder();
    builder.setCodeSpace(EPSG, "EPSG").setRequired(true);
    return new ParameterDescriptor<?>[] { builder.addIdentifier("8801").addName("Latitude of natural origin").setRemarks(remarks).create(0, Units.DEGREE), builder.addIdentifier("8802").addName("Longitude of natural origin").create(0, Units.DEGREE) };
}
Also used : GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterDescriptor(org.opengis.parameter.ParameterDescriptor) DefaultParameterDescriptor(org.apache.sis.parameter.DefaultParameterDescriptor) ParameterBuilder(org.apache.sis.parameter.ParameterBuilder)

Example 9 with ParameterDescriptor

use of org.opengis.parameter.ParameterDescriptor in project sis by apache.

the class ParameterBuilderTest method testMercatorProjection.

/**
 * Tests the <cite>"Mercator (variant A)"</cite> example given in Javadoc.
 */
@Test
@DependsOnMethod("testCreate")
@SuppressWarnings("UnnecessaryBoxing")
public void testMercatorProjection() {
    final ParameterBuilder builder = new ParameterBuilder();
    builder.setCodeSpace(Citations.EPSG, "EPSG").setRequired(true);
    final ParameterDescriptor<?>[] parameters = { builder.addName("Longitude of natural origin").addName(Citations.OGC, "central_meridian").addName(Citations.GEOTIFF, "NatOriginLong").setRemarks("Some remarks.").createBounded(-180, +180, 0, Units.DEGREE), builder.addName("Latitude of natural origin").createBounded(-80, +84, 0, Units.DEGREE), builder.addName("Scale factor at natural origin").createStrictlyPositive(1, Units.UNITY), builder.addName("False easting").create(0, Units.METRE), builder.addName("False northing").create(0, Units.METRE) };
    // Tests random properties.
    assertEquals("EPSG", parameters[1].getName().getCodeSpace());
    assertEquals("False easting", parameters[3].getName().getCode());
    assertEquals("Some remarks.", parameters[0].getRemarks().toString());
    assertEquals(Double.valueOf(84), parameters[1].getMaximumValue());
    assertEquals(Units.METRE, parameters[4].getUnit());
    assertTrue(parameters[1].getAlias().isEmpty());
    final GenericName alias = parameters[0].getAlias().iterator().next();
    assertEquals("central_meridian", alias.tip().toString());
    assertEquals("OGC", alias.head().toString());
    assertEquals("OGC:central_meridian", alias.toString());
}
Also used : GenericName(org.opengis.util.GenericName) ParameterDescriptor(org.opengis.parameter.ParameterDescriptor) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 10 with ParameterDescriptor

use of org.opengis.parameter.ParameterDescriptor in project sis by apache.

the class SingleOperationMarshallingTest method createMercatorMethod.

/**
 * Creates the test operation method.
 */
private static DefaultOperationMethod createMercatorMethod() {
    final ParameterBuilder builder = new ParameterBuilder();
    builder.setCodeSpace(EPSG, "EPSG").setRequired(true);
    ParameterDescriptor<?>[] parameters = { builder.addIdentifier("8801").addName("Latitude of natural origin").create(0, Units.DEGREE), builder.addIdentifier("8802").addName("Longitude of natural origin").create(0, Units.DEGREE) // There is more parameters for a Mercator projection, but 2 is enough for this test.
    };
    builder.addName(null, "Mercator (1SP)");
    final ParameterDescriptorGroup descriptor = builder.createGroup(parameters);
    final Map<String, Object> properties = new HashMap<>(4);
    properties.put(DefaultOperationMethod.NAME_KEY, descriptor.getName());
    properties.put(DefaultOperationMethod.FORMULA_KEY, new DefaultFormula("See EPSG guide."));
    return new DefaultOperationMethod(properties, 2, 2, descriptor);
}
Also used : HashMap(java.util.HashMap) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterDescriptor(org.opengis.parameter.ParameterDescriptor) ParameterDescriptorGroup(org.opengis.parameter.ParameterDescriptorGroup) ParameterBuilder(org.apache.sis.parameter.ParameterBuilder)

Aggregations

ParameterDescriptor (org.opengis.parameter.ParameterDescriptor)12 GeneralParameterDescriptor (org.opengis.parameter.GeneralParameterDescriptor)7 ParameterDescriptorGroup (org.opengis.parameter.ParameterDescriptorGroup)5 ParameterBuilder (org.apache.sis.parameter.ParameterBuilder)4 Test (org.junit.Test)4 DefaultParameterDescriptor (org.apache.sis.parameter.DefaultParameterDescriptor)3 DefaultParameterDescriptorGroup (org.apache.sis.parameter.DefaultParameterDescriptorGroup)3 DependsOnMethod (org.apache.sis.test.DependsOnMethod)3 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)2 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)2 OperationMethod (org.opengis.referencing.operation.OperationMethod)2 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 EnumMap (java.util.EnumMap)1 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 CC_OperationParameterGroupTest (org.apache.sis.internal.jaxb.referencing.CC_OperationParameterGroupTest)1 ObliqueStereographic (org.apache.sis.internal.referencing.provider.ObliqueStereographic)1 FormattableObject (org.apache.sis.io.wkt.FormattableObject)1