Class LinearTransformBuilder


  • public class LinearTransformBuilder
    extends TransformBuilder
    Creates an affine transform which will map approximately the given source positions to the given target positions. In many cases, the source positions are grid indices and the target positions are geographic or projected coordinates, but this is not mandatory. If the source positions are known to be grid indices, then a builder created by the Linear­Transform­Builder(int...) constructor will be more efficient. Otherwise a builder created by the Linear­Transform­Builder() constructor will be able to handle randomly distributed coordinates.

    Builders are not thread-safe. Builders can be used only once; points can not be added or modified after create(Math­Transform­Factory) has been invoked. The transform coefficients are determined using a least squares estimation method, with the assumption that source positions are exact and all the uncertainty is in the target positions.

    Linearizers
    Consider the following situation (commonly found with netCDF files): the sources coordinates are pixel indices and the targets are (longitude, latitude) coordinates, but we suspect that the sources to targets transform is some undetermined map projection, maybe Mercator. A linear approximation between those coordinates will give poor results; the results would be much better if all (longitude, latitude) coordinates were converted to the right projection first. However that map projection may not be known, but we can try to guess it by trials-and-errors using a set of plausible projections. That set can be specified by add­Linearizers(Map, int...). If the create(Math­Transform­Factory) method finds that one of the specified projections seems a good fit, it will automatically convert all target coordinates to that projection. That selected projection is given by linearizer().
    Since:
    0.5
    See Also:
    Localization­Grid­Builder, Linear­Transform, Line, Plane

    Defined in the sis-referencing module

    • Constructor Detail

      • LinearTransformBuilder

        public LinearTransformBuilder()
        Creates a new linear transform builder for randomly distributed positions.
        Tip: if the source coordinates are grid indices, then the Linear­Transform­Builder(int...) constructor will create a more efficient builder.
      • LinearTransformBuilder

        public LinearTransformBuilder​(int... gridSize)
        Creates a new linear transform builder for source positions distributed on a regular grid. This constructor notifies Linear­Transform­Builder that coordinate values of all source positions will be integers in the [0 … grid­Size[0]-1] range for the first dimension (typically column indices), in the [0 … grid­Size[1]-1] range for the second dimension (typically row indices), etc. The dimension of all source positions is the length of the given grid­Size array.

        An empty array is equivalent to invoking the no-argument constructor, i.e. no restriction is put on the source coordinates.

        Parameters:
        grid­Size - the number of integer coordinate values in each grid dimension.
        Throws:
        Illegal­Argument­Exception - if a grid size is not strictly positive, or if the product of all values (∏grid­Size) is greater than Integer​.MAX_VALUE.
        Since:
        0.8
    • Method Detail

      • getSourceEnvelope

        public Envelope getSourceEnvelope()
        Returns the envelope of source points (keys of the map returned by get­Control­Points()). The number of dimensions is equal to get­Source­Dimensions(). This method returns the known minimum and maximum values (inclusive) for each dimension, not expanded to encompass full cell surfaces. In other words, the returned envelope encompasses only cell centers.

        If a grid size was specified at construction time, then those minimums and maximums are inferred from the grid size and are always integer values. Otherwise, the minimums and maximums are extracted from the control points and may be any floating point values. In any cases, the lower and upper values are inclusive.

        Returns:
        the envelope of source points (cell centers), inclusive.
        Throws:
        Illegal­State­Exception - if the source points are not yet known.
        Since:
        1.0
      • setControlPoints

        public void setControlPoints​(Map<? extends Position,​? extends Position> sourceToTarget)
                              throws MismatchedDimensionException
        Sets all matching control point pairs, overwriting any previous setting. The source positions are the keys in the given map, and the target positions are the associated values in the map. The map should not contain two entries with the same source position. Coordinate reference systems are ignored. Null positions are silently ignored. Positions with NaN or infinite coordinates cause an exception to be thrown.

        All source positions shall have the same number of dimensions (the source dimension), and all target positions shall have the same number of dimensions (the target dimension). However the source dimension does not need to be the same than the target dimension. Apache SIS currently supports only one- or two-dimensional source positions, together with arbitrary target dimension.

        If this builder has been created with the Linear­Transform­Builder(int...) constructor, then the coordinate values of all source positions shall be integers in the [0 … grid­Size[0]-1] range for the first dimension (typically column indices), in the [0 … grid­Size[1]-1] range for the second dimension (typically row indices), etc. This constraint does not apply for builders created with the Linear­Transform­Builder() constructor.

        Parameters:
        source­To­Target - a map of source positions to target positions. Source positions are assumed precise and target positions are assumed uncertain.
        Throws:
        Illegal­State­Exception - if create(…) has already been invoked.
        Illegal­Argument­Exception - if the given positions contain NaN or infinite coordinate values.
        Illegal­Argument­Exception - if this builder has been created for a grid but some source coordinates are not indices in that grid.
        Mismatched­Dimension­Exception - if some positions do not have the expected number of dimensions.
        Since:
        0.8
      • getControlPoints

        public Map<DirectPosition,​DirectPosition> getControlPoints()
        Returns all control points as a map. Values are source coordinates and keys are target coordinates. The map is unmodifiable and is guaranteed to contain only non-null keys and values. The map is a view: changes in this builder are immediately reflected in the returned map.

        If linearizer() returns a non-empty value, then the values in the returned map are projected using that linearizer. This may happen only after create(…) has been invoked.

        Returns:
        all control points in this builder.
        Since:
        1.0
      • setControlPoint

        public void setControlPoint​(int[] source,
                                    double[] target)
        Sets a single matching control point pair. Source position is assumed precise and target position is assumed uncertain. If the given source position was already associated with another target position, then the old target position is discarded.
        Performance note: current implementation is efficient for builders created for a grid but inefficient for builders created for randomly distributed points. In the later case, the set­Control­Points(Map) method is a more efficient alternative.
        Parameters:
        source - the source coordinates. If this builder has been created with the Linear­Transform­Builder(int...) constructor, then for every index i the source[i] value shall be in the [0 … grid­Size[i]-1] range inclusive. If this builder has been created with the Linear­Transform­Builder() constructor, then no constraint apply.
        target - the target coordinates, assumed uncertain.
        Throws:
        Illegal­State­Exception - if create(…) has already been invoked.
        Illegal­Argument­Exception - if this builder has been created for a grid but some source coordinates are out of index range, or if target contains NaN of infinite numbers.
        Mismatched­Dimension­Exception - if the source or target position does not have the expected number of dimensions.
        Since:
        0.8
      • addLinearizers

        public void addLinearizers​(Map<String,​MathTransform> projections,
                                   int... projToGrid)
        Adds transforms to potentially apply on target coordinates before to compute the linear transform. This method can be invoked if one suspects that the source to target transform may be more linear when the target is another space than the current space of target coordinates. If linearizers have been specified, then the create(Math­Transform­Factory) method will try to apply each transform on target coordinates and check which one results in the best correlation coefficients. It may be none.

        The linearizers are specified as Math­Transforms from current target coordinates to other spaces where sources to new targets transforms may be more linear. Keys in the map are arbitrary identifiers used in to­String() for debugging purpose. Values in the map are non-Linear­Transforms (linear transforms are not forbidden, but are useless for this process).

        The proj­To­Grid argument maps projections dimensions to this builder target dimensions. For example if proj­To­Grid array is {2,1}, then dimensions 0 and 1 of given projections (both source and target dimensions) will map to dimensions 2 and 1 of this builder target dimensions, respectively. The proj­To­Grid argument can be omitted or null, in which {0, 1, 2 … get­Target­Dimensions() - 1} is assumed. All given projections shall have a number of source and target dimensions equals to the length of the given or assumed proj­To­Grid array. It is possible to invoke this method many times with different proj­To­Grid argument values.

        Parameters:
        projections - projections from current target coordinates to other spaces which may result in more linear transforms.
        proj­To­Grid - the target dimensions to project, or null or omitted for projecting all target dimensions.
        Throws:
        Illegal­State­Exception - if create(…) has already been invoked.
        Since:
        1.0
        See Also:
        linearizer(), correlation()
      • create

        public LinearTransform create​(MathTransformFactory factory)
                               throws FactoryException
        Creates a linear transform approximation from the source positions to the target positions. This method assumes that source positions are precise and that all uncertainty is in the target positions. If linearizers have been specified, then this method may project all target coordinates using one of those linearizers in order to get a more linear transform. If such projection is applied, then linearizer() will return a non-empty value after this method call.

        If this method is invoked more than once, the previously created transform instance is returned.

        Specified by:
        create in class Transform­Builder
        Parameters:
        factory - the factory to use for creating the transform, or null for the default factory. The Math­Transform­Factory​.create­Affine­Transform(Matrix) method of that factory shall return Linear­Transform instances.
        Returns:
        the fitted linear transform.
        Throws:
        Factory­Exception - if the transform can not be created, for example because the source or target points have not be specified.
        Since:
        0.8
      • linearizer

        public Optional<MathTransform> linearizer()
        If target coordinates have been projected to another space, returns that projection. This method returns a non-empty value only if all the following conditions are met:
        1. add­Linearizers(Map, int...) has been invoked.
        2. create(Math­Transform­Factory) has been invoked.
        3. The create(…) method at step 2 found that projecting target coordinates using one of the linearizers specified at step 1 results in a more linear transform.
        If this method returns a non-empty value, then the envelope returned by get­Target­Envelope() and all control points returned by get­Control­Point(int[]) are projected by this transform. The returned transform includes axes swapping specified by the dimensions argument given to add­Linearizers(…, dimensions).
        Returns:
        the projection applied on target coordinates before to compute a linear transform.
        Since:
        1.0
      • correlation

        public double[] correlation()
        Returns the Pearson correlation coefficients of the transform created by create(…). The closer those coefficients are to +1 or -1, the better the fit. This method returns null if create(…) has not yet been invoked. If non-null, the array length is equal to the number of target dimensions.
        Returns:
        estimation of Pearson correlation coefficients for each target dimension, or null if create(…) has not been invoked yet.
      • toString

        public String toString()
        Returns a string representation of this builder for debugging purpose. Current implementation shows the following information:
        • Number of points.
        • Linearizers and their correlation coefficients (if available).
        • The linear transform (if already computed).
        The string representation may change in any future version.
        Overrides:
        to­String in class Object
        Returns:
        a string representation of this builder.