| /* |
| * 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.geometry; |
| |
| /* |
| * Do not add dependency to java.awt.Rectangle2D in this class, because not every platforms |
| * support Java2D (e.g. Android), or applications that do not need it may want to avoid to |
| * force installation of the Java2D module (e.g. JavaFX/SWT). |
| */ |
| import java.io.Serializable; |
| import org.opengis.geometry.Envelope; |
| import org.opengis.geometry.DirectPosition; |
| import org.opengis.geometry.MismatchedDimensionException; |
| import org.opengis.geometry.MismatchedReferenceSystemException; |
| import org.opengis.referencing.crs.CoordinateReferenceSystem; |
| import org.opengis.metadata.extent.GeographicBoundingBox; |
| |
| import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches; |
| |
| |
| /** |
| * An immutable {@code Envelope} (a minimum bounding box or rectangle) of arbitrary dimension. |
| * This class is final in order to ensure that the immutability contract can not be broken |
| * (assuming not using <cite>Java Native Interface</cite> or reflections). |
| * |
| * <h2>Immutability and thread safety</h2> |
| * This final class is immutable and thus inherently thread-safe if the {@link CoordinateReferenceSystem} |
| * instance given to the constructor is immutable. This is usually the case in Apache SIS. |
| * |
| * @author Cédric Briançon (Geomatys) |
| * @author Martin Desruisseaux (IRD, Geomatys) |
| * @version 0.3 |
| * @since 0.3 |
| * @module |
| */ |
| public final class ImmutableEnvelope extends ArrayEnvelope implements Serializable { |
| /** |
| * For cross-version compatibility. |
| */ |
| private static final long serialVersionUID = 8740224085449107870L; |
| |
| /** |
| * Constructs an envelope defined by two corners given as direct positions. |
| * The envelope CRS will be the CRS of the given positions. |
| * |
| * @param lowerCorner the limits in the direction of decreasing coordinate values for each dimension. |
| * @param upperCorner the limits in the direction of increasing coordinate values for each dimension. |
| * @throws MismatchedDimensionException if the two positions do not have the same dimension. |
| * @throws MismatchedReferenceSystemException if the CRS of the two position are not equal. |
| */ |
| public ImmutableEnvelope(final DirectPosition lowerCorner, final DirectPosition upperCorner) |
| throws MismatchedDimensionException, MismatchedReferenceSystemException |
| { |
| super(lowerCorner, upperCorner); |
| } |
| |
| /** |
| * Constructs an envelope defined by two corners given as sequences of coordinate values. |
| * |
| * @param lowerCorner the limits in the direction of decreasing coordinate values for each dimension. |
| * @param upperCorner the limits in the direction of increasing coordinate values for each dimension. |
| * @param crs the CRS to assign to this envelope, or {@code null}. |
| * @throws MismatchedDimensionException if the two sequences do not have the same length, or |
| * if the dimension of the given CRS is not equals to the dimension of the given corners. |
| */ |
| public ImmutableEnvelope(final double[] lowerCorner, final double[] upperCorner, |
| final CoordinateReferenceSystem crs) throws MismatchedDimensionException |
| { |
| super(lowerCorner, upperCorner); |
| this.crs = crs; |
| ensureDimensionMatches("crs", getDimension(), crs); |
| } |
| |
| /** |
| * Constructs a new envelope with the same data than the specified geographic bounding box. |
| * The coordinate reference system is set to the |
| * {@linkplain org.apache.sis.referencing.CommonCRS#defaultGeographic() default geographic CRS}. |
| * Axis order is (<var>longitude</var>, <var>latitude</var>). |
| * |
| * @param box the bounding box to copy. |
| */ |
| public ImmutableEnvelope(final GeographicBoundingBox box) { |
| super(box); |
| } |
| |
| /** |
| * Creates an immutable envelope with the values of the given envelope. |
| * This constructor can be used when the given envelope is known to not |
| * be an instance of {@code ImmutableEnvelope}. In case of doubt, |
| * consider using {@link #castOrCopy(Envelope)} instead. |
| * |
| * @param envelope the envelope to copy. |
| * |
| * @see #castOrCopy(Envelope) |
| */ |
| public ImmutableEnvelope(final Envelope envelope) { |
| super(envelope); |
| } |
| |
| /** |
| * Creates an immutable envelope with the coordinate values of the given envelope but |
| * a different CRS. This method does <strong>not</strong> reproject the given envelope. |
| * It just assign the given CRS to this envelope without any check, except for the CRS |
| * dimension. |
| * |
| * <p>The main purpose of this method is to assign a non-null CRS when the envelope to |
| * copy has a null CRS.</p> |
| * |
| * @param crs the CRS to assign to this envelope, or {@code null}. |
| * @param envelope the envelope from which to copy coordinate values. |
| * @throws MismatchedDimensionException if the dimension of the given CRS is not equals |
| * to the dimension of the given envelope. |
| */ |
| public ImmutableEnvelope(final CoordinateReferenceSystem crs, final Envelope envelope) |
| throws MismatchedDimensionException |
| { |
| super(envelope); |
| this.crs = crs; |
| ensureDimensionMatches("crs", getDimension(), crs); |
| } |
| |
| /** |
| * Constructs a new envelope initialized to the values parsed from the given string in |
| * {@code BOX} or <cite>Well Known Text</cite> (WKT) format. The given string is typically |
| * a {@code BOX} element like below: |
| * |
| * {@preformat wkt |
| * BOX(-180 -90, 180 90) |
| * } |
| * |
| * However this constructor is lenient to other geometry types like {@code POLYGON}. |
| * See the javadoc of the {@link GeneralEnvelope#GeneralEnvelope(CharSequence) GeneralEnvelope} |
| * constructor for more information. |
| * |
| * @param crs the coordinate reference system, or {@code null} if none. |
| * @param wkt the {@code BOX}, {@code POLYGON} or other kind of element to parse. |
| * @throws IllegalArgumentException if the given string can not be parsed. |
| * @throws MismatchedDimensionException if the dimension of the given CRS is not equals |
| * to the dimension of the parsed envelope. |
| */ |
| public ImmutableEnvelope(final CoordinateReferenceSystem crs, final CharSequence wkt) |
| throws IllegalArgumentException, MismatchedDimensionException |
| { |
| super(wkt); |
| this.crs = crs; |
| ensureDimensionMatches("crs", getDimension(), crs); |
| } |
| |
| /** |
| * Returns the given envelope as an {@code ImmutableEnvelope} instance. If the given envelope |
| * is already an instance of {@code ImmutableEnvelope}, then it is returned unchanged. |
| * Otherwise the coordinate values and the CRS of the given envelope are copied in a |
| * new envelope. |
| * |
| * @param envelope the envelope to cast, or {@code null}. |
| * @return the values of the given envelope as an {@code ImmutableEnvelope} instance. |
| * |
| * @see AbstractEnvelope#castOrCopy(Envelope) |
| * @see GeneralEnvelope#castOrCopy(Envelope) |
| */ |
| public static ImmutableEnvelope castOrCopy(final Envelope envelope) { |
| if (envelope == null || envelope instanceof ImmutableEnvelope) { |
| return (ImmutableEnvelope) envelope; |
| } |
| return new ImmutableEnvelope(envelope); |
| } |
| } |