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;
}