private static CoordinateSystem createCS()

in endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtentCRS.java [243:380]


    private static CoordinateSystem createCS(final int tgtDim, final Matrix gridToCRS,
            final DimensionNameType[] types, final Locale locale) throws FactoryException
    {
        int srcDim = types.length;      // Used only for inspecting names. No need to be accurate.
        if (gridToCRS != null) {
            srcDim = Math.min(gridToCRS.getNumCol() - 1, srcDim);
        }
        final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[tgtDim];
        final CSFactory csFactory = GeodeticObjectFactory.provider();
        boolean hasVertical = false;
        boolean hasTime     = false;
        boolean hasOther    = false;
        for (int i=0; i<srcDim; i++) {
            final DimensionNameType type = types[i];
            if (type != null) {
                /*
                 * Try to locate the CRS dimension corresponding to grid dimension j.
                 * We expect a one-to-one matching; if it is not the case, return null.
                 * Current version does not accept scale factors, but we could revisit
                 * in a future version if there is a need for it.
                 */
                int target = i;
                double scale = 0;
                if (gridToCRS != null) {
                    target = -1;
                    for (int j=0; j<tgtDim; j++) {
                        final double m = gridToCRS.getElement(j, i);
                        if (m != 0) {
                            if (target >= 0 || axes[j] != null || Math.abs(m) != 1) {
                                return null;
                            }
                            target = j;
                            scale  = m;
                        }
                    }
                    if (target < 0) {
                        return null;
                    }
                }
                /*
                 * This hard-coded set of axis directions is the converse of
                 * GridExtent.AXIS_DIRECTIONS map.
                 */
                String abbreviation;
                AxisDirection direction;
                if (type == DimensionNameType.COLUMN || type == DimensionNameType.SAMPLE) {
                    abbreviation = "x"; direction = AxisDirection.COLUMN_POSITIVE;
                } else if (type == DimensionNameType.ROW || type == DimensionNameType.LINE) {
                    abbreviation = "y"; direction = AxisDirection.ROW_POSITIVE;
                } else if (type == DimensionNameType.VERTICAL) {
                    abbreviation = "z"; direction = AxisDirection.UP; hasVertical = true;
                } else if (type == DimensionNameType.TIME) {
                    abbreviation = "t"; direction = AxisDirection.FUTURE; hasTime = true;
                } else {
                    abbreviation = abbreviation(target);
                    direction = AxisDirections.UNSPECIFIED;
                    hasOther = true;
                }
                /*
                 * Verify that no other axis has the same direction and abbreviation. If duplicated
                 * values are found, keep only the first occurrence in grid axis order (may not be
                 * the CRS axis order).
                 */
                for (int k = tgtDim; --k >= 0;) {
                    final CoordinateSystemAxis previous = axes[k];
                    if (previous != null) {
                        if (direction.equals(AxisDirections.absolute(previous.getDirection()))) {
                            direction = AxisDirections.UNSPECIFIED;
                            hasOther = true;
                        }
                        if (abbreviation.equals(previous.getAbbreviation())) {
                            abbreviation = abbreviation(target);
                        }
                    }
                }
                if (scale < 0) {
                    direction = AxisDirections.opposite(direction);
                }
                final String name = Types.toString(Types.getCodeTitle(type), locale);
                axes[target] = axis(csFactory, name, abbreviation, direction);
            }
        }
        /*
         * Search for axes that have not been created in above loop.
         * It happens when some axes have no associated `DimensionNameType` code.
         */
        for (int j=0; j<tgtDim; j++) {
            if (axes[j] == null) {
                final String name = Vocabulary.forLocale(locale).getString(Vocabulary.Keys.Dimension_1, j);
                final String abbreviation = abbreviation(j);
                axes[j] = axis(csFactory, name, abbreviation, AxisDirections.UNSPECIFIED);
            }
        }
        /*
         * Create a coordinate system of affine type if all axes seem spatial.
         * If no specialized type seems to fit, use an unspecified ("abstract")
         * coordinate system type in last resort.
         */
        final Map<String,?> properties = properties(CS_NAME);
        final CoordinateSystem cs;
        if (hasOther || (tgtDim > (hasTime ? 1 : 3))) {
            cs = new AbstractCS(properties, axes);
        } else switch (tgtDim) {
            case 1:  {
                final CoordinateSystemAxis axis = axes[0];
                if (hasVertical) {
                    cs = csFactory.createVerticalCS(properties, axis);
                } else if (hasTime) {
                    cs = csFactory.createTimeCS(properties, axis);
                } else {
                    cs = csFactory.createLinearCS(properties, axis);
                }
                break;
            }
            case 2: {
                /*
                 * A null `gridToCRS` means that we are creating a CS for the grid, which is assumed a
                 * Cartesian space. A non-null value means that we are creating a CRS for a transformed
                 * envelope, in which case the CS type is not really known.
                 */
                cs = (gridToCRS == null)
                        ? csFactory.createCartesianCS(properties, axes[0], axes[1])
                        : csFactory.createAffineCS   (properties, axes[0], axes[1]);
                break;
            }
            case 3: {
                cs = (gridToCRS == null)
                        ? csFactory.createCartesianCS(properties, axes[0], axes[1], axes[2])
                        : csFactory.createAffineCS   (properties, axes[0], axes[1], axes[2]);
                break;
            }
            default: {
                cs = null;
                break;
            }
        }
        return cs;
    }