You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2022/07/29 17:16:06 UTC
[sis] branch geoapi-4.0 updated (877b832e88 -> 02d0e99b52)
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
from 877b832e88 fix(Storage): fix GeoTiff resource finding
new ce6fa1494e Minor consolidation of the GeoTIFF name parsing. The only functional change is that the full namespace is checked instead of only the direct parent. This is for consistency with the default implementation of `findResource(String)` in `DataStore`. This comparison is easier to do on `String` objects, which also avoid creation of temporary `GenericName`.
new a5c010b654 Use a spherical model for GCOM-C data with Sinusoidal Equal Area projection.
new 02d0e99b52 Add a "Pseudo sinusoidal" projection similar to Pseudo Mercator: use spherical formulas but apply the result on WGS84 ellipsoid.
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../java/org/apache/sis/util/iso/AbstractName.java | 15 ++---
.../apache/sis/util/iso/DefaultNameFactory.java | 9 +--
.../org/apache/sis/util/iso/DefaultNameSpace.java | 33 ++++++++++-
.../org/apache/sis/util/iso/DefaultRecordType.java | 4 +-
.../java/org/apache/sis/util/iso/package-info.java | 2 +-
...sOrderReversal3D.java => PseudoSinusoidal.java} | 35 ++++++-----
.../internal/referencing/provider/Sinusoidal.java | 22 ++++---
.../referencing/operation/projection/Mercator.java | 2 +-
.../operation/projection/Sinusoidal.java | 64 +++++++++++++++++++--
.../operation/projection/package-info.java | 2 +-
...g.opengis.referencing.operation.OperationMethod | 1 +
.../referencing/provider/ProvidersTest.java | 3 +-
.../java/org/apache/sis/util/resources/Errors.java | 10 ++--
.../apache/sis/util/resources/Errors.properties | 2 +-
.../apache/sis/util/resources/Errors_fr.properties | 2 +-
.../apache/sis/internal/earth/netcdf/GCOM_C.java | 6 +-
.../sis/internal/earth/netcdf/package-info.java | 2 +-
.../apache/sis/storage/geotiff/GeoTiffStore.java | 67 +++++++++++-----------
.../sis/storage/geotiff/SelfConsistencyTest.java | 29 ++++++----
.../org/apache/sis/internal/netcdf/Convention.java | 4 ++
.../apache/sis/internal/netcdf/GridMapping.java | 5 +-
21 files changed, 210 insertions(+), 109 deletions(-)
copy core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/{AxisOrderReversal3D.java => PseudoSinusoidal.java} (57%)
[sis] 01/03: Minor consolidation of the GeoTIFF name parsing. The only functional change is that the full namespace is checked instead of only the direct parent. This is for consistency with the default implementation of `findResource(String)` in `DataStore`. This comparison is easier to do on `String` objects, which also avoid creation of temporary `GenericName`.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit ce6fa1494e6d21473005b7f827c29e835f6b2ab6
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Jul 29 14:57:04 2022 +0200
Minor consolidation of the GeoTIFF name parsing.
The only functional change is that the full namespace is checked instead of only the direct parent.
This is for consistency with the default implementation of `findResource(String)` in `DataStore`.
This comparison is easier to do on `String` objects, which also avoid creation of temporary `GenericName`.
As minor changes, the separator is fetched from the namespace (but it should not make a difference in practice),
the scope of `try ... catch` blocks is make narrower, the error message for unexpected namespace is localized,
and the test case verifies the error message.
---
.../java/org/apache/sis/util/iso/AbstractName.java | 15 ++---
.../apache/sis/util/iso/DefaultNameFactory.java | 9 +--
.../org/apache/sis/util/iso/DefaultNameSpace.java | 33 ++++++++++-
.../org/apache/sis/util/iso/DefaultRecordType.java | 4 +-
.../java/org/apache/sis/util/iso/package-info.java | 2 +-
.../java/org/apache/sis/util/resources/Errors.java | 10 ++--
.../apache/sis/util/resources/Errors.properties | 2 +-
.../apache/sis/util/resources/Errors_fr.properties | 2 +-
.../apache/sis/storage/geotiff/GeoTiffStore.java | 67 +++++++++++-----------
.../sis/storage/geotiff/SelfConsistencyTest.java | 29 ++++++----
10 files changed, 99 insertions(+), 74 deletions(-)
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/AbstractName.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/AbstractName.java
index 89e8faa7bb..26b31ae973 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/AbstractName.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/AbstractName.java
@@ -277,14 +277,9 @@ public abstract class AbstractName implements GenericName, Serializable {
* @param name the name after which to write a separator.
* @return the separator to write after the given name.
*/
- static String separator(final GenericName name) {
- if (name != null) {
- final NameSpace scope = name.scope();
- if (scope instanceof DefaultNameSpace) {
- return ((DefaultNameSpace) scope).headSeparator;
- }
- }
- return DefaultNameSpace.DEFAULT_SEPARATOR_STRING;
+ private static String headSeparator(final GenericName name) {
+ return (name != null) ? DefaultNameSpace.getSeparator(name.scope(), true)
+ : DefaultNameSpace.DEFAULT_SEPARATOR_STRING;
}
/**
@@ -310,7 +305,7 @@ public abstract class AbstractName implements GenericName, Serializable {
final StringBuilder buffer = new StringBuilder();
for (final LocalName name : getParsedNames()) {
if (insertSeparator) {
- buffer.append(separator(name));
+ buffer.append(headSeparator(name));
}
insertSeparator = true;
buffer.append(name);
@@ -383,7 +378,7 @@ public abstract class AbstractName implements GenericName, Serializable {
final StringBuilder buffer = new StringBuilder();
for (final LocalName name : parsedNames) {
if (insertSeparator) {
- buffer.append(separator(name));
+ buffer.append(headSeparator(name));
}
insertSeparator = true;
buffer.append(name.toInternationalString().toString(locale));
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
index cc78ce2a56..92fcc67b5d 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
@@ -37,8 +37,6 @@ import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.collection.WeakHashSet;
import org.apache.sis.internal.util.Strings;
-import static org.apache.sis.util.iso.DefaultNameSpace.DEFAULT_SEPARATOR_STRING;
-
/**
* A factory for creating {@link AbstractName} objects.
@@ -294,12 +292,7 @@ public class DefaultNameFactory extends AbstractFactory implements NameFactory {
*/
@Override
public GenericName parseGenericName(final NameSpace scope, final CharSequence name) {
- final String separator;
- if (scope instanceof DefaultNameSpace) {
- separator = ((DefaultNameSpace) scope).separator;
- } else {
- separator = DEFAULT_SEPARATOR_STRING;
- }
+ final String separator = DefaultNameSpace.getSeparator(scope, false);
final int s = separator.length();
final List<String> names = new ArrayList<>();
int lower = 0;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
index d0ba3d84e7..9fbe7bdfb4 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
@@ -52,7 +52,7 @@ import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
* remain safe to call from multiple threads and do not change any public {@code NameSpace} state.
*
* @author Martin Desruisseaux (IRD, Geomatys)
- * @version 0.8
+ * @version 1.3
*
* @see DefaultScopedName
* @see DefaultLocalName
@@ -98,12 +98,16 @@ public class DefaultNameSpace implements NameSpace, Serializable {
/**
* The separator to insert between the namespace and the {@linkplain AbstractName#head() head}
* of any name in that namespace.
+ *
+ * @see #getSeparator(NameSpace, boolean)
*/
- final String headSeparator;
+ private final String headSeparator;
/**
* The separator to insert between the {@linkplain AbstractName#getParsedNames() parsed names}
* of any name in that namespace.
+ *
+ * @see #getSeparator(NameSpace, boolean)
*/
final String separator;
@@ -252,6 +256,31 @@ public class DefaultNameSpace implements NameSpace, Serializable {
return ns;
}
+ /**
+ * Returns the separator between name components in the given namespace.
+ * If the given namespace is an instance of {@code DefaultNameSpace}, then this method
+ * returns the {@code headSeparator} or {@code separator} argument given to the constructor.
+ * Otherwise this method returns the {@linkplain #DEFAULT_SEPARATOR default separator}.
+ *
+ * <div class="note"><b>API note:</b>
+ * this method is static because the {@code getSeparator(…)} method is not part of GeoAPI interfaces.
+ * A static method makes easier to use without {@code (if (x instanceof DefaultNameSpace)} checks.</div>
+ *
+ * @param ns the namespace for which to get the separator. May be {@code null}.
+ * @param head {@code true} for the separator between namespace and {@linkplain AbstractName#head() head}, or
+ * {@code false} for the separator between {@linkplain AbstractName#getParsedNames() parsed names}.
+ * @return separator between name components.
+ *
+ * @since 1.3
+ */
+ public static String getSeparator(final NameSpace ns, final boolean head) {
+ if (ns instanceof DefaultNameSpace) {
+ final DefaultNameSpace ds = (DefaultNameSpace) ns;
+ return head ? ds.headSeparator : ds.separator;
+ }
+ return DEFAULT_SEPARATOR_STRING;
+ }
+
/**
* Indicates whether this namespace is a "top level" namespace. Global, or top-level
* namespaces are not contained within another namespace. The global namespace has no
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
index 19919c24b9..60d6bfc1ee 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
@@ -169,7 +169,7 @@ public class DefaultRecordType extends RecordDefinition implements RecordType, S
final LocalName schemaName = container.getSchemaName();
final GenericName fullTypeName = typeName.toFullyQualifiedName();
if (schemaName.compareTo(typeName.scope().name().tip()) != 0) {
- throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2, schemaName, fullTypeName));
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.UnexpectedNamespace_2, schemaName, fullTypeName));
}
final int size = size();
for (int i=0; i<size; i++) {
@@ -179,7 +179,7 @@ public class DefaultRecordType extends RecordDefinition implements RecordType, S
throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalMemberType_2, name, type));
}
if (fullTypeName.compareTo(name.scope().name()) != 0) {
- throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2,
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.UnexpectedNamespace_2,
fullTypeName, name.toFullyQualifiedName()));
}
}
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/package-info.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/package-info.java
index fadfbb6c39..105afcdbb4 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/package-info.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/package-info.java
@@ -99,7 +99,7 @@
* </table>
*
* @author Martin Desruisseaux (IRD, Geomatys)
- * @version 1.1
+ * @version 1.3
* @since 0.3
* @module
*/
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
index 7b3d1dfe90..de7a0030d2 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
@@ -476,11 +476,6 @@ public final class Errors extends IndexedResourceBundle {
*/
public static final short InconsistentAttribute_2 = 67;
- /**
- * Expected “{0}” namespace for “{1}”.
- */
- public static final short InconsistentNamespace_2 = 68;
-
/**
* Inconsistent table columns.
*/
@@ -896,6 +891,11 @@ public final class Errors extends IndexedResourceBundle {
*/
public static final short UnexpectedFileFormat_2 = 139;
+ /**
+ * The “{1}” name is not valid in this context, because the “{0}” namespace was expected.
+ */
+ public static final short UnexpectedNamespace_2 = 68;
+
/**
* Parameter “{0}” was not expected.
*/
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
index 8ea926426d..ec0853a874 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
@@ -106,7 +106,6 @@ IncompatibleUnit_1 = Unit \u201c{0}\u201d is incompatible with cu
IncompatibleUnits_2 = Units \u201c{0}\u201d and \u201c{1}\u201d are incompatible.
IncompatibleUnitDimension_5 = The \u201c{0}\u201d unit of measurement has dimension of \u2018{1}\u2019 ({2}). It is incompatible with dimension of \u2018{3}\u2019 ({4}).
InconsistentAttribute_2 = Value \u201c{1}\u201d of attribute \u2018{0}\u2019 is inconsistent with other attributes.
-InconsistentNamespace_2 = Expected \u201c{0}\u201d namespace for \u201c{1}\u201d.
InconsistentTableColumns = Inconsistent table columns.
InconsistentUnitsForCS_1 = Unit of measurement \u201c{0}\u201d is inconsistent with coordinate system axes.
IndexOutOfBounds_1 = Index {0} is out of bounds.
@@ -190,6 +189,7 @@ UnexpectedCharactersAtBound_4 = Text for \u2018{0}\u2019 was expected to {1,
UnexpectedEndOfFile_1 = Unexpected end of file while reading \u201c{0}\u201d.
UnexpectedEndOfString_1 = More characters were expected at the end of \u201c{0}\u201d.
UnexpectedFileFormat_2 = File \u201c{1}\u201d seems to be encoded in an other format than {0}.
+UnexpectedNamespace_2 = The \u201c{1}\u201d name is not valid in this context, because the \u201c{0}\u201d namespace was expected.
UnexpectedParameter_1 = Parameter \u201c{0}\u201d was not expected.
UnexpectedProperty_2 = Property \u201c{1}\u201d was not expected in \u201c{0}\u201d.
UnexpectedScaleFactorForUnit_2 = Unexpected scale factor {1,number} for unit of measurement \u201c{0}\u201d.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
index 673dd4df77..305e55dfd6 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
@@ -103,7 +103,6 @@ IncompatibleUnit_1 = L\u2019unit\u00e9 \u00ab\u202f{0}\u202f\u00b
IncompatibleUnits_2 = Les unit\u00e9s \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb ne sont pas compatibles.
IncompatibleUnitDimension_5 = L\u2019unit\u00e9 de mesure \u00ab\u202f{0}\u202f\u00bb a la dimension de \u2018{1}\u2019 ({2}). Elle est incompatible avec la dimension de \u2018{3}\u2019 ({4}).
InconsistentAttribute_2 = La valeur \u00ab\u202f{1}\u202f\u00bb de l\u2019attribut \u2018{0}\u2019 n\u2019est pas coh\u00e9rente avec celles des autres attributs.
-InconsistentNamespace_2 = L\u2019espace de nom \u201c{0}\u201d \u00e9tait attendu pour \u201c{1}\u201d.
InconsistentTableColumns = Les colonnes des tables ne sont pas coh\u00e9rentes.
InconsistentUnitsForCS_1 = L\u2019unit\u00e9 de mesure \u00ab\u202f{0}\u202f\u00bb n\u2019est pas coh\u00e9rente avec les axes du syst\u00e8me de coordonn\u00e9es.
IndexOutOfBounds_1 = L\u2019index {0} est en dehors des limites permises.
@@ -186,6 +185,7 @@ UnexpectedCharactersAtBound_4 = Le texte pour \u2018{0}\u2019 devait {1,choi
UnexpectedEndOfFile_1 = Fin de fichier inattendue lors de la lecture de \u00ab\u202f{0}\u202f\u00bb.
UnexpectedEndOfString_1 = D\u2019autres caract\u00e8res \u00e9taient attendus \u00e0 la fin du texte \u00ab\u202f{0}\u202f\u00bb.
UnexpectedFileFormat_2 = Le fichier \u00ab\u202f{1}\u202f\u00bb semble \u00eatre encod\u00e9 dans un autre format que {0}.
+UnexpectedNamespace_2 = Le nom \u201c{1}\u201d n\u2019est pas valide dans ce contexte, parce que l\u2019espace de nom \u201c{0}\u201d \u00e9tait attendu.
UnexpectedParameter_1 = Le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb est inattendu.
UnexpectedProperty_2 = La propri\u00e9t\u00e9 \u00ab\u202f{1}\u202f\u00bb est inattendue dans \u00ab\u202f{0}\u202f\u00bb.
UnexpectedScaleFactorForUnit_2 = Le facteur d\u2019\u00e9chelle {1,number} est inattendu pour l\u2019unit\u00e9 de mesure \u00ab\u202f{0}\u202f\u00bb.
diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
index 81b0b121cf..6995585ad3 100644
--- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
+++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
@@ -25,9 +25,6 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
-import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.NullArgumentException;
-import org.apache.sis.util.iso.Names;
import org.opengis.util.NameSpace;
import org.opengis.util.NameFactory;
import org.opengis.util.GenericName;
@@ -59,7 +56,9 @@ import org.apache.sis.metadata.iso.DefaultMetadata;
import org.apache.sis.metadata.sql.MetadataStoreException;
import org.apache.sis.util.collection.BackingStoreException;
import org.apache.sis.util.collection.TreeTable;
+import org.apache.sis.util.iso.DefaultNameSpace;
import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.ArgumentChecks;
/**
@@ -68,6 +67,7 @@ import org.apache.sis.util.resources.Errors;
* @author Rémi Maréchal (Geomatys)
* @author Martin Desruisseaux (Geomatys)
* @author Thi Phuong Hao Nguyen (VNSC)
+ * @author Alexis Manin (Geomatys)
* @version 1.3
* @since 0.8
* @module
@@ -469,6 +469,7 @@ public class GeoTiffStore extends DataStore implements Aggregate {
/**
* Returns the image at the given index. Images numbering starts at 1.
+ * If the given string has a scope (e.g. "filename:1"), then the scope
*
* @param sequence string representation of the image index, starting at 1.
* @return image at the given index.
@@ -476,50 +477,50 @@ public class GeoTiffStore extends DataStore implements Aggregate {
*/
@Override
public synchronized GridCoverageResource findResource(final String sequence) throws DataStoreException {
- try {
- final int index = parseIndex(sequence);
+ ArgumentChecks.ensureNonNull("sequence", sequence);
+ final int index = parseImageIndex(sequence);
+ if (index >= 0) try {
final GridCoverageResource image = reader().getImage(index - 1);
if (image != null) return image;
- } catch (NullArgumentException | IllegalArgumentException e) {
- throw new IllegalNameException(StoreUtilities.resourceNotFound(this, sequence), e);
} catch (IOException e) {
throw errorIO(e);
}
-
throw new IllegalNameException(StoreUtilities.resourceNotFound(this, sequence));
}
/**
- * Validate input resource name and extract the image index it should contain.
- * We verify that:
+ * Validates input resource name and extracts the image index it should contain.
+ * The resource name may be of the form "1" or "filename:1". We verify that:
+ *
* <ul>
- * <li>Input tip (last name part) is a strictly positive integer ({@code > 0})</li>
- * <li>
- * If input provide more than a tip, i.e has more than one name part,
- * we verify that the part just before the tip matches this datastore namespace
- * (should be the name of the Geotiff file without its extension).
- * </li>
+ * <li>Input tip (last name part) is a parsable integer.</li>
+ * <li>If input provides more than a tip, all test before the tip matches this datastore namespace
+ * (should be the name of the Geotiff file without its extension).</li>
* </ul>
*
- * @param resourceName A string representing the name of a resource present in this datastore.
- * @return The index of the Geotiff image matching the requested resource.
- * @throws IllegalArgumentException If input validation fails.
+ * @param sequence a string representing the name of a resource present in this datastore.
+ * @return the index of the Geotiff image matching the requested resource.
+ * There is no verification that the returned index is valid.
+ * @throws IllegalNameException if the argument use an invalid namespace or if the tip is not an integer.
*/
- private int parseIndex(String resourceName) {
- final GenericName name = Names.parseGenericName(null, null, resourceName);
- final String tip = name.tip().toString();
- ArgumentChecks.ensureNonEmpty("Resource name tip", tip);
-
- final int depth = name.depth();
- if (depth > 1) {
- final GenericName userNameSpace = name.getParsedNames().get(depth - 2);
- final GenericName storeNameSpace = namespace().name();
- if (!userNameSpace.equals(storeNameSpace)) throw new IllegalArgumentException(
- "Input name head does not match this datastore context. Expected: " + storeNameSpace + " but received: " + userNameSpace);
+ private int parseImageIndex(String sequence) throws IllegalNameException {
+ final NameSpace namespace = namespace();
+ final String separator = DefaultNameSpace.getSeparator(namespace, false);
+ final int s = sequence.lastIndexOf(separator);
+ if (s >= 0) {
+ if (namespace != null) {
+ final String expected = namespace.name().toString();
+ if (!sequence.substring(0, s).equals(expected)) {
+ throw new IllegalNameException(errors().getString(Errors.Keys.UnexpectedNamespace_2, expected, sequence));
+ }
+ }
+ sequence = sequence.substring(s + separator.length());
+ }
+ try {
+ return Integer.parseInt(sequence);
+ } catch (NumberFormatException e) {
+ throw new IllegalNameException(StoreUtilities.resourceNotFound(this, sequence), e);
}
- final int index = Integer.parseInt(tip);
- ArgumentChecks.ensureStrictlyPositive("Resource index", index);
- return index;
}
/**
diff --git a/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java b/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java
index 333402ae8a..48ad7fb6ce 100644
--- a/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java
+++ b/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java
@@ -19,6 +19,7 @@ package org.apache.sis.storage.geotiff;
import java.util.List;
import java.util.Optional;
import java.nio.file.Path;
+import org.opengis.util.GenericName;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.GridCoverageResource;
import org.apache.sis.storage.IllegalNameException;
@@ -26,12 +27,10 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.test.OptionalTestData;
import org.apache.sis.test.storage.CoverageReadConsistency;
import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.opengis.util.GenericName;
+import static org.junit.Assert.*;
import static org.junit.Assume.assumeNotNull;
@@ -43,7 +42,8 @@ import static org.junit.Assume.assumeNotNull;
* a subset of data.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @author Alexis Manin (Geomatys)
+ * @version 1.3
* @since 1.1
* @module
*/
@@ -90,24 +90,31 @@ public final strictfp class SelfConsistencyTest extends CoverageReadConsistency
super(store.components().iterator().next());
}
+ /**
+ * Verifies that {@link GeoTiffStore#findResource(String)} returns the resource when using
+ * either the full name or only its tip.
+ *
+ * @throws DataStoreException if an error occurred while reading the file.
+ */
@Test
- public void findResourceByName() throws Exception {
+ public void findResourceByName() throws DataStoreException {
final List<GridCoverageResource> datasets = store.components();
- Assume.assumeFalse(datasets.isEmpty());
+ assertFalse(datasets.isEmpty());
for (GridCoverageResource dataset : datasets) {
final GenericName name = dataset.getIdentifier()
.orElseThrow(() -> new AssertionError("A component of the GeoTiff datastore is unnamed"));
GridCoverageResource foundResource = store.findResource(name.toString());
- Assert.assertEquals(dataset, foundResource);
+ assertSame(dataset, foundResource);
foundResource = store.findResource(name.tip().toString());
- Assert.assertEquals(dataset, foundResource);
+ assertSame(dataset, foundResource);
}
-
try {
final GridCoverageResource r = store.findResource("a_wrong_namespace:1");
- Assert.fail("No dataset should be returned when user specify the wrong namespace. However, the datastore returned "+ r);
+ fail("No dataset should be returned when user specify the wrong namespace. However, the datastore returned " + r);
} catch (IllegalNameException e) {
- // Expected behaviour
+ // Expected behaviour.
+ final String message = e.getMessage();
+ assertTrue(message, message.contains("a_wrong_namespace:1"));
}
}
}
[sis] 03/03: Add a "Pseudo sinusoidal" projection similar to Pseudo Mercator: use spherical formulas but apply the result on WGS84 ellipsoid.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit 02d0e99b52ba03cad63fe867e74a65fe9c7d35eb
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Jul 29 15:38:45 2022 +0200
Add a "Pseudo sinusoidal" projection similar to Pseudo Mercator:
use spherical formulas but apply the result on WGS84 ellipsoid.
https://issues.apache.org/jira/browse/SIS-553
---
.../referencing/provider/PseudoSinusoidal.java | 59 ++++++++++++++++++++
.../internal/referencing/provider/Sinusoidal.java | 22 +++++---
.../referencing/operation/projection/Mercator.java | 2 +-
.../operation/projection/Sinusoidal.java | 64 ++++++++++++++++++++--
.../operation/projection/package-info.java | 2 +-
...g.opengis.referencing.operation.OperationMethod | 1 +
.../referencing/provider/ProvidersTest.java | 3 +-
.../apache/sis/internal/earth/netcdf/GCOM_C.java | 11 +---
8 files changed, 139 insertions(+), 25 deletions(-)
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PseudoSinusoidal.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PseudoSinusoidal.java
new file mode 100644
index 0000000000..bcf34efe4b
--- /dev/null
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PseudoSinusoidal.java
@@ -0,0 +1,59 @@
+/*
+ * 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.internal.referencing.provider;
+
+import javax.xml.bind.annotation.XmlTransient;
+import org.opengis.parameter.ParameterDescriptorGroup;
+
+
+/**
+ * The provider for <cite>"Pseudo sinusoidal equal-area"</cite> projection.
+ * This is similar to Pseudo-Mercator: uses spherical formulas but apply the result on an ellipsoid.
+ * This is sometime used with remote sensing data.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 1.3
+ * @since 1.3
+ * @module
+ */
+@XmlTransient
+public final class PseudoSinusoidal extends Sinusoidal {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = 6523477856049963388L;
+
+ /**
+ * Name of this projection.
+ */
+ public static final String NAME = "Pseudo sinusoidal";
+
+ /**
+ * The group of all parameters expected by this coordinate operation.
+ */
+ private static ParameterDescriptorGroup parameters() {
+ return builder().addName(NAME)
+ .createGroupForMapProjection(AbstractMercator.toArray(PARAMETERS.descriptors(), 0));
+ }
+
+ /**
+ * Constructs a new provider.
+ */
+ public PseudoSinusoidal() {
+ super(parameters());
+ }
+}
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Sinusoidal.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Sinusoidal.java
index 3c3dfff3fd..81a249ae55 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Sinusoidal.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Sinusoidal.java
@@ -32,7 +32,7 @@ import org.apache.sis.referencing.operation.projection.NormalizedProjection;
* This projection method has no associated EPSG code.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.3
*
* @see <a href="https://en.wikipedia.org/wiki/Sinusoidal_projection">Sinusoidal projection on Wikipedia</a>
* @see <a href="http://geotiff.maptools.org/proj_list/sinusoidal.html">GeoTIFF parameters for Sinusoidal</a>
@@ -41,17 +41,12 @@ import org.apache.sis.referencing.operation.projection.NormalizedProjection;
* @module
*/
@XmlTransient
-public final class Sinusoidal extends MapProjection {
+public class Sinusoidal extends MapProjection {
/**
* For cross-version compatibility.
*/
private static final long serialVersionUID = -3236247448683326299L;
- /**
- * Name of this projection.
- */
- public static final String NAME = "Sinusoidal";
-
/**
* The operation parameter descriptor for the <cite>Longitude of projection center</cite> (λ₀) parameter value.
* Valid values range is [-180 … 180]° and default value is 0°.
@@ -97,10 +92,10 @@ public final class Sinusoidal extends MapProjection {
/**
* The group of all parameters expected by this coordinate operation.
*/
- private static final ParameterDescriptorGroup PARAMETERS;
+ static final ParameterDescriptorGroup PARAMETERS;
static {
PARAMETERS = builder().setCodeSpace(Citations.OGC, Constants.OGC)
- .addName (NAME)
+ .addName ("Sinusoidal")
.addName ("Sanson-Flamsteed")
.addName (Citations.GEOTIFF, "CT_Sinusoidal")
.addIdentifier(Citations.GEOTIFF, "24")
@@ -115,6 +110,15 @@ public final class Sinusoidal extends MapProjection {
super(PARAMETERS);
}
+ /**
+ * Constructs a math transform provider from a set of parameters.
+ *
+ * @param parameters the set of parameters (never {@code null}).
+ */
+ Sinusoidal(final ParameterDescriptorGroup parameters) {
+ super(parameters);
+ }
+
/**
* {@inheritDoc}
*
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
index 90097ef0a1..6a669f5edc 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
@@ -381,7 +381,7 @@ public class Mercator extends ConformalProjection {
@Override
public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
NormalizedProjection kernel = this;
-subst: if ((variant.spherical || eccentricity == 0) && getClass() == Mercator.class) {
+subst: if (variant.spherical || (eccentricity == 0 && getClass() == Mercator.class)) {
if (variant == Variant.AUXILIARY && eccentricity != 0) {
final int type = context.getValue(MercatorAuxiliarySphere.AUXILIARY_SPHERE_TYPE);
if (type == AuthalicMercator.TYPE) {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Sinusoidal.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Sinusoidal.java
index 808d9e439d..70283f04e3 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Sinusoidal.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Sinusoidal.java
@@ -17,6 +17,7 @@
package org.apache.sis.referencing.operation.projection;
import java.util.EnumMap;
+import java.util.regex.Pattern;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.referencing.operation.Matrix;
@@ -41,7 +42,7 @@ import static org.apache.sis.internal.referencing.provider.Sinusoidal.*;
* </ul>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.3
* @since 1.0
* @module
*/
@@ -51,17 +52,61 @@ public class Sinusoidal extends MeridianArcBased {
*/
private static final long serialVersionUID = 7908925241331303236L;
+ /**
+ * Variants of Sinusoidal projection. Those variants modify the way the projections are constructed
+ * (e.g. in the way parameters are interpreted), but formulas are basically the same after construction.
+ *
+ * <p>We do not provide such codes in public API because they duplicate the functionality of
+ * {@link OperationMethod} instances. We use them only for constructors convenience.</p>
+ */
+ private enum Variant implements ProjectionVariant {
+ // Declaration order matter. Patterns are matched in that order.
+
+ /** The <cite>"Pseudo sinusoidal equal-area"</cite> projection. */
+ PSEUDO(".*\\bPseudo.*");
+
+ /** Name pattern for this variant. */
+ private final Pattern operationName;
+
+ /** Creates a new enumeration value. */
+ private Variant(final String operationName) {
+ this.operationName = Pattern.compile(operationName, Pattern.CASE_INSENSITIVE);
+ }
+
+ /** The expected name pattern of an operation method for this variant. */
+ @Override public Pattern getOperationNamePattern() {
+ return operationName;
+ }
+
+ /** EPSG identifier of an operation method for this variant. */
+ @Override public String getIdentifier() {
+ return null;
+ }
+ }
+
+ /**
+ * The type of sinusoidal projection. Possible values are:
+ * <ul>
+ * <li>{@link Variant#PSEUDO} if this projection is the "Pseudo sinusoidal equal-area" case.</li>
+ * <li>{@code null} for the standard case.</li>
+ * </ul>
+ *
+ * Other cases may be added in the future.
+ */
+ private final Variant variant;
+
/**
* Work around for RFE #4093999 in Sun's bug database
* ("Relax constraint on placement of this()/super() call in constructors").
*/
@Workaround(library="JDK", version="1.8")
private static Initializer initializer(final OperationMethod method, final Parameters parameters) {
+ final Variant variant = variant(method, Variant.values(), null);
final EnumMap<ParameterRole, ParameterDescriptor<Double>> roles = new EnumMap<>(ParameterRole.class);
roles.put(ParameterRole.CENTRAL_MERIDIAN, CENTRAL_MERIDIAN);
roles.put(ParameterRole.FALSE_EASTING, FALSE_EASTING);
roles.put(ParameterRole.FALSE_NORTHING, FALSE_NORTHING);
- return new Initializer(method, parameters, roles, null);
+ return new Initializer(method, parameters, roles, variant);
}
/**
@@ -76,7 +121,17 @@ public class Sinusoidal extends MeridianArcBased {
* @param parameters the parameter values of the projection to create.
*/
public Sinusoidal(final OperationMethod method, final Parameters parameters) {
- super(initializer(method, parameters));
+ this(initializer(method, parameters));
+ }
+
+ /**
+ * Work around for RFE #4093999 in Sun's bug database
+ * ("Relax constraint on placement of this()/super() call in constructors").
+ */
+ @Workaround(library="JDK", version="1.7")
+ private Sinusoidal(final Initializer initializer) {
+ super(initializer);
+ variant = (Variant) initializer.variant;
}
/**
@@ -84,6 +139,7 @@ public class Sinusoidal extends MeridianArcBased {
*/
Sinusoidal(final Sinusoidal other) {
super(other);
+ variant = other.variant;
}
/**
@@ -101,7 +157,7 @@ public class Sinusoidal extends MeridianArcBased {
@Override
public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
Sinusoidal kernel = this;
- if (eccentricity == 0 && getClass() == Sinusoidal.class) {
+ if ((eccentricity == 0 && getClass() == Sinusoidal.class) || variant == Variant.PSEUDO) {
kernel = new Spherical(this);
}
return context.completeTransform(factory, kernel);
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java
index f2ad34531e..0fa929c114 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java
@@ -160,7 +160,7 @@
* @author Rémi Maréchal (Geomatys)
* @author Adrian Custer (Geomatys)
* @author Matthieu Bastianelli (Geomatys)
- * @version 1.2
+ * @version 1.3
*
* @see <a href="https://mathworld.wolfram.com/MapProjection.html">Map projections on MathWorld</a>
*
diff --git a/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod b/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
index 52f61edf69..a1ac1bfbf8 100644
--- a/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
+++ b/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
@@ -64,6 +64,7 @@ org.apache.sis.internal.referencing.provider.ModifiedAzimuthalEquidistant
org.apache.sis.internal.referencing.provider.AzimuthalEquidistantSpherical
org.apache.sis.internal.referencing.provider.ZonedTransverseMercator
org.apache.sis.internal.referencing.provider.Sinusoidal
+org.apache.sis.internal.referencing.provider.PseudoSinusoidal
org.apache.sis.internal.referencing.provider.Polyconic
org.apache.sis.internal.referencing.provider.Mollweide
org.apache.sis.internal.referencing.provider.SouthPoleRotation
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
index fb24e65e70..f13cda4040 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
@@ -36,7 +36,7 @@ import static org.junit.Assert.*;
* Tests {@link Providers} and some consistency rules of all providers defined in this package.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
* @since 0.6
* @module
*/
@@ -114,6 +114,7 @@ public final strictfp class ProvidersTest extends TestCase {
ZonedTransverseMercator.class,
SatelliteTracking.class,
Sinusoidal.class,
+ PseudoSinusoidal.class,
Polyconic.class,
Mollweide.class,
SouthPoleRotation.class,
diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
index d21d264952..8ec93cd0b7 100644
--- a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
+++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
@@ -37,7 +37,7 @@ import org.apache.sis.internal.netcdf.Variable;
import org.apache.sis.internal.netcdf.VariableRole;
import org.apache.sis.internal.netcdf.Linearizer;
import org.apache.sis.internal.netcdf.Node;
-import org.apache.sis.internal.referencing.provider.Sinusoidal;
+import org.apache.sis.internal.referencing.provider.PseudoSinusoidal;
import org.apache.sis.internal.referencing.provider.Equirectangular;
import org.apache.sis.internal.referencing.provider.PolarStereographicA;
import org.apache.sis.referencing.operation.transform.TransferFunction;
@@ -361,13 +361,11 @@ public final class GCOM_C extends Convention {
if (name == null) {
return super.projection(node);
}
- Number radius = null;
final String method;
final int s = name.indexOf(' ');
final String code = (s >= 0) ? name.substring(0, s) : name;
if (code.equalsIgnoreCase("EQA")) {
- method = Sinusoidal.NAME;
- radius = 6371000; // "Not specified (based on Authalic Sphere)" datum (EPSG:6035).
+ method = PseudoSinusoidal.NAME;
} else if (code.equalsIgnoreCase("EQR")) {
method = Equirectangular.NAME;
} else if (code.equalsIgnoreCase("PS")) {
@@ -378,11 +376,6 @@ public final class GCOM_C extends Convention {
final Map<String,Object> definition = new HashMap<>(4);
definition.put(CF.GRID_MAPPING_NAME, method);
definition.put(CONVERSION_NAME, name);
- if (radius != null) {
- definition.put(CF.SEMI_MAJOR_AXIS, radius);
- definition.put(CF.SEMI_MINOR_AXIS, radius);
- definition.put(ELLIPSOID_NAME, "Authalic sphere");
- }
return definition;
}
[sis] 02/03: Use a spherical model for GCOM-C data with Sinusoidal Equal Area projection.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit a5c010b654410c9775b1550b38af3021ccafeae7
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Jul 26 14:08:08 2022 +0200
Use a spherical model for GCOM-C data with Sinusoidal Equal Area projection.
---
.../main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java | 9 ++++++++-
.../java/org/apache/sis/internal/earth/netcdf/package-info.java | 2 +-
.../src/main/java/org/apache/sis/internal/netcdf/Convention.java | 4 ++++
.../main/java/org/apache/sis/internal/netcdf/GridMapping.java | 5 ++++-
4 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
index e81c9efb36..d21d264952 100644
--- a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
+++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
@@ -117,7 +117,7 @@ import ucar.nc2.constants.CF;
*
* @author Alexis Manin (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
*
* @see <a href="http://global.jaxa.jp/projects/sat/gcom_c/">SHIKISAI (GCOM-C) on JAXA</a>
* @see <a href="https://en.wikipedia.org/wiki/Global_Change_Observation_Mission">GCOM on Wikipedia</a>
@@ -361,11 +361,13 @@ public final class GCOM_C extends Convention {
if (name == null) {
return super.projection(node);
}
+ Number radius = null;
final String method;
final int s = name.indexOf(' ');
final String code = (s >= 0) ? name.substring(0, s) : name;
if (code.equalsIgnoreCase("EQA")) {
method = Sinusoidal.NAME;
+ radius = 6371000; // "Not specified (based on Authalic Sphere)" datum (EPSG:6035).
} else if (code.equalsIgnoreCase("EQR")) {
method = Equirectangular.NAME;
} else if (code.equalsIgnoreCase("PS")) {
@@ -376,6 +378,11 @@ public final class GCOM_C extends Convention {
final Map<String,Object> definition = new HashMap<>(4);
definition.put(CF.GRID_MAPPING_NAME, method);
definition.put(CONVERSION_NAME, name);
+ if (radius != null) {
+ definition.put(CF.SEMI_MAJOR_AXIS, radius);
+ definition.put(CF.SEMI_MINOR_AXIS, radius);
+ definition.put(ELLIPSOID_NAME, "Authalic sphere");
+ }
return definition;
}
diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/package-info.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/package-info.java
index 1381a2a517..e0f420d726 100644
--- a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/package-info.java
+++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/package-info.java
@@ -21,7 +21,7 @@
*
* @author Alexis Manin (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.3
* @since 1.0
* @module
*/
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
index f14865a487..67ea796b7a 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
@@ -459,6 +459,10 @@ public class Convention {
* <td>{@link Number} or {@code double[]}</td>
* <td>Map projection parameter values</td>
* </tr><tr>
+ * <td>{@value CF#SEMI_MAJOR_AXIS} and {@value CF#SEMI_MINOR_AXIS}</td>
+ * <td>{@link Number}</td>
+ * <td>Ellipsoid axis lengths.</td>
+ * </tr><tr>
* <td>{@value #TOWGS84}</td>
* <td>{@link BursaWolfParameters}</td>
* <td>Datum shift information.</td>
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java
index 54c914905d..839e69c98b 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java
@@ -309,7 +309,10 @@ final class GridMapping {
meridian = defaultDefinitions.primeMeridian();
}
/*
- * Ellipsoid built from "semi_major_axis", "semi_minor_axis", etc.
+ * Ellipsoid built from "semi_major_axis" and "semi_minor_axis" parameters. Note that it is okay
+ * to use the OGC name (e.g. "semi_major") instead of the netCDF name (e.g. ""semi_major_axis").
+ * The Apache SIS implementation of parameter value group understands the aliases. Using the OGC
+ * names is safer because they should be understood by most map projection implementations.
*/
Ellipsoid ellipsoid;
try {