Search in sources :

Example 1 with NullArgumentException

use of org.apache.sis.util.NullArgumentException in project sis by apache.

the class CodeListSet method add.

/**
 * Adds the specified code list element in this set.
 *
 * @param  element  the code list element to add in this set.
 * @return {@code true} if this set has been modified as a consequence of this method call.
 */
@Override
public boolean add(final E element) {
    if (element == null) {
        final String message = CheckedArrayList.illegalElement(this, element, elementType);
        if (message == null) {
            /*
                 * If a unmarshalling process is under way, silently discard null element.
                 * This case happen when a codeListValue attribute in a XML file is empty.
                 * See https://issues.apache.org/jira/browse/SIS-157
                 */
            return false;
        }
        throw new NullArgumentException(message);
    }
    int ordinal = element.ordinal();
    if (ordinal < Long.SIZE) {
        return values != (values |= (1L << ordinal));
    }
    /*
         * The above code is suffisient in the vast majority of cases. In the rare cases where
         * there is more than 64 elements, create a BitSet for storing the supplementary values.
         */
    BitSet s = supplementary;
    if (s == null) {
        supplementary = s = new BitSet();
    }
    if (s.get(ordinal -= Long.SIZE)) {
        return false;
    }
    s.set(ordinal);
    return true;
}
Also used : BitSet(java.util.BitSet) NullArgumentException(org.apache.sis.util.NullArgumentException)

Example 2 with NullArgumentException

use of org.apache.sis.util.NullArgumentException in project sis by apache.

the class DefaultCoordinateOperationFactory method createSingleOperation.

/**
 * Creates a transformation or conversion from the given properties.
 * This method infers by itself if the operation to create is a
 * {@link Transformation}, a {@link Conversion} or a {@link Projection} sub-type
 * ({@link CylindricalProjection}, {@link ConicProjection} or {@link PlanarProjection})
 * using the {@linkplain DefaultOperationMethod#getOperationType() information provided by the given method}.
 *
 * <p>The properties given in argument follow the same rules than for the
 * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem,
 * CoordinateReferenceSystem, CoordinateReferenceSystem, MathTransform) coordinate operation} constructor.
 * The following table is a reminder of main (not all) properties:</p>
 *
 * <table class="sis">
 *   <caption>Recognized properties (non exhaustive list)</caption>
 *   <tr>
 *     <th>Property name</th>
 *     <th>Value type</th>
 *     <th>Returned by</th>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
 *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
 *     <td>{@link DefaultConversion#getName()}</td>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
 *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
 *     <td>{@link DefaultConversion#getIdentifiers()}</td>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}</td>
 *     <td>{@link org.opengis.metadata.extent.Extent}</td>
 *     <td>{@link DefaultConversion#getDomainOfValidity()}</td>
 *   </tr>
 * </table>
 *
 * @param  properties        the properties to be given to the identified object.
 * @param  sourceCRS         the source CRS.
 * @param  targetCRS         the target CRS.
 * @param  interpolationCRS  the CRS of additional coordinates needed for the operation, or {@code null} if none.
 * @param  method            the coordinate operation method (mandatory in all cases).
 * @param  transform         transform from positions in the source CRS to positions in the target CRS.
 * @return the coordinate operation created from the given arguments.
 * @throws FactoryException if the object creation failed.
 *
 * @see DefaultOperationMethod#getOperationType()
 * @see DefaultTransformation
 * @see DefaultConversion
 */
public SingleOperation createSingleOperation(final Map<String, ?> properties, final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS, final CoordinateReferenceSystem interpolationCRS, final OperationMethod method, MathTransform transform) throws FactoryException {
    ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
    ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
    ArgumentChecks.ensureNonNull("method", method);
    /*
         * Undocumented (for now) feature: if the 'transform' argument is null but parameters are
         * found in the given properties, create the MathTransform instance from those parameters.
         * This is needed for WKT parsing of CoordinateOperation[…] among others.
         */
    if (transform == null) {
        final ParameterValueGroup parameters = Containers.property(properties, ReferencingServices.PARAMETERS_KEY, ParameterValueGroup.class);
        if (parameters == null) {
            throw new NullArgumentException(Errors.format(Errors.Keys.NullArgument_1, "transform"));
        }
        transform = getMathTransformFactory().createBaseToDerived(sourceCRS, parameters, targetCRS.getCoordinateSystem());
    }
    /*
         * The "operationType" property is currently undocumented. The intent is to help this factory method in
         * situations where the given operation method is not an Apache SIS implementation or does not override
         * getOperationType(), or the method is ambiguous (e.g. "Affine" can be used for both a transformation
         * or a conversion).
         *
         * If we have both a 'baseType' and a Method.getOperationType(), take the most specific type.
         * An exception will be thrown if the two types are incompatible.
         */
    Class<?> baseType = Containers.property(properties, ReferencingServices.OPERATION_TYPE_KEY, Class.class);
    if (baseType == null) {
        baseType = SingleOperation.class;
    }
    if (method instanceof DefaultOperationMethod) {
        final Class<? extends SingleOperation> c = ((DefaultOperationMethod) method).getOperationType();
        if (c != null) {
            // Paranoiac check (above method should not return null).
            if (baseType.isAssignableFrom(c)) {
                baseType = c;
            } else if (!c.isAssignableFrom(baseType)) {
                throw new IllegalArgumentException(Errors.format(Errors.Keys.IncompatiblePropertyValue_1, ReferencingServices.OPERATION_TYPE_KEY));
            }
        }
    }
    /*
         * If the base type is still abstract (probably because it was not specified neither in the given OperationMethod
         * or in the properties), then try to find a concrete type using the following rules derived from the definitions
         * given in ISO 19111:
         *
         *   - If the two CRS uses the same datum (ignoring metadata), assume that we have a Conversion.
         *   - Otherwise we have a datum change, which implies that we have a Transformation.
         *
         * In the case of Conversion, we can specialize one step more if the conversion is going from a geographic CRS
         * to a projected CRS. It may seems that we should check if ProjectedCRS.getBaseCRS() is equals (ignoring meta
         * data) to source CRS. But we already checked the datum, which is the important part. The axis order and unit
         * could be different, which we want to allow.
         */
    if (baseType == SingleOperation.class) {
        if (isConversion(sourceCRS, targetCRS)) {
            if (interpolationCRS == null && sourceCRS instanceof GeographicCRS && targetCRS instanceof ProjectedCRS) {
                baseType = Projection.class;
            } else {
                baseType = Conversion.class;
            }
        } else {
            baseType = Transformation.class;
        }
    }
    /*
         * Now create the coordinate operation of the requested type. If we can not find a concrete class for the
         * requested type, we will instantiate a SingleOperation in last resort.  The later action is a departure
         * from ISO 19111 since 'SingleOperation' is conceptually abstract.  But we do that as a way to said that
         * we are missing this important piece of information but still go ahead.
         *
         * It is inconvenient to guarantee that the created operation is an instance of 'baseType' since the user
         * could have specified an implementation class or a custom sub-interface. We will perform the type check
         * only after object creation.
         */
    final AbstractSingleOperation op;
    if (Transformation.class.isAssignableFrom(baseType)) {
        op = new DefaultTransformation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
    } else if (Projection.class.isAssignableFrom(baseType)) {
        ArgumentChecks.ensureCanCast("sourceCRS", GeographicCRS.class, sourceCRS);
        ArgumentChecks.ensureCanCast("targetCRS", ProjectedCRS.class, targetCRS);
        if (interpolationCRS != null) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.ForbiddenAttribute_2, "interpolationCRS", baseType));
        }
        final GeographicCRS baseCRS = (GeographicCRS) sourceCRS;
        final ProjectedCRS crs = (ProjectedCRS) targetCRS;
        if (CylindricalProjection.class.isAssignableFrom(baseType)) {
            op = new DefaultCylindricalProjection(properties, baseCRS, crs, method, transform);
        } else if (ConicProjection.class.isAssignableFrom(baseType)) {
            op = new DefaultConicProjection(properties, baseCRS, crs, method, transform);
        } else if (PlanarProjection.class.isAssignableFrom(baseType)) {
            op = new DefaultPlanarProjection(properties, baseCRS, crs, method, transform);
        } else {
            op = new DefaultProjection(properties, baseCRS, crs, method, transform);
        }
    } else if (Conversion.class.isAssignableFrom(baseType)) {
        op = new DefaultConversion(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
    } else {
        // See above comment about this last-resort fallback.
        op = new AbstractSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
    }
    if (!baseType.isInstance(op)) {
        throw new FactoryException(Resources.format(Resources.Keys.CanNotCreateObjectAsInstanceOf_2, baseType, op.getName()));
    }
    return pool.unique(op);
}
Also used : ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) FactoryException(org.opengis.util.FactoryException) NullArgumentException(org.apache.sis.util.NullArgumentException) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) GeographicCRS(org.opengis.referencing.crs.GeographicCRS)

Aggregations

NullArgumentException (org.apache.sis.util.NullArgumentException)2 BitSet (java.util.BitSet)1 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)1 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)1 ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)1 FactoryException (org.opengis.util.FactoryException)1