Class WraparoundInEnvelope

All Implemented Interfaces:
Serializable, Parameterized, LenientComparable, org.opengis.referencing.operation.MathTransform

final class WraparoundInEnvelope extends WraparoundTransform
A WraparoundTransform where the number of cycles added or removed does not exceed a given limit. The bound is determined by whether the coordinate to transform is before or after a median point. If the coordinate is before the median, this class puts a limit on the number of cycles added. If the coordinate is after the median, this class puts a limit on the number of cycles removed. The intent is to avoid that the lower bound of an envelope is shifted by a greater number of cycles than the upper bound, which may result in lower bound becoming greater than upper bound.

The median point is WraparoundTransform.sourceMedian. It is used as the source coordinate where the minimum or maximum number of cycles is determined. This source coordinate is not necessarily the same as the median target coordinate (which is fixed to zero by application of normalization matrix) because those medians were determined from source and target envelopes, which do not need to be the same.

The final result is that envelopes transformed using WraparoundInEnvelope may be larger than envelopes transformed using WraparoundTransform but should never be smaller. For example, when transforming the following envelope with wraparound on the dashed line:

Mutability

This class is mutable. This class records the translations that shift(double) wanted to apply but could not because of the limit documented in above paragraph. When such missed translations are detected, caller should translate the limit and transform same envelope again. We do that because each envelope transformation should use a consistent limit for all corners. Since this strategy breaks usual AbstractMathTransform contract about immutability, this class should be used only for temporary transforms to apply on an envelope.

Thread-safety

This class is not thread-safe. Each instance shall be used by only one thread. Temporary instances should be created by the thread doing transformations and discarded immediately after.
Since:
1.1
Version:
1.1
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      For cross-version compatibility.
      See Also:
    • limit

      private double limit
      Number of cycles at the WraparoundTransform.sourceMedian position. This is the minimum or maximum number of cycles to remove to a coordinate, depending if that coordinate is before or after the median.
    • minCycles

      private double minCycles
      The minimum and maximum number of periods that shift(double) wanted to add to the coordinate before to be constrained to the limit.
    • maxCycles

      private double maxCycles
      The minimum and maximum number of periods that shift(double) wanted to add to the coordinate before to be constrained to the limit.
    • minChanged

      private boolean minChanged
      Whether minCycles or maxCycles has been updated.
    • maxChanged

      private boolean maxChanged
      Whether minCycles or maxCycles has been updated.
  • Constructor Details

    • WraparoundInEnvelope

      private WraparoundInEnvelope(WraparoundTransform other)
      Creates a new transform initialized to a copy of given instance. Input and output values in the wraparound dimension shall be normalized in the [−p/2 … +p/2] range where p is the period (e.g. 360°).
  • Method Details

    • shift

      protected final double shift(double x)
      Applies the wraparound on the given coordinate value. This implementation ensures that coordinates smaller than WraparoundTransform.sourceMedian before wraparound are still smaller than the (possibly shifted) median after wraparound, and conversely for coordinates greater than the median. The final result is that envelopes transformed using WraparoundInEnvelope may be larger than envelopes transformed using WraparoundTransform but should never be smaller.
      Overrides:
      shift in class WraparoundTransform
      Parameters:
      x - the value on which to apply wraparound.
      Returns:
      the value after wraparound.
      See Also:
    • translate

      private boolean translate()
      Modifies this transform with a translation for enabling the wraparound that could not be applied in previous shift(double) executions. If this method returns true, then this transform will now compute different output coordinates for the same input coordinates.

      Usage

      This method can be invoked after transforming an envelope. If this method returns true, then the same envelope should be transformed again and the new result added to the previous result (union).
      Returns:
      true if this transform has been modified.