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 610221887288ac6ea4ffe10331b869658fb31c51 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Wed Jan 18 17:50:52 2023 +0100 Try to resolve ambiguity between "Polar Stereographic (variant A)" and "(variant B)" in GeoTIFF files. --- .../org/apache/sis/storage/geotiff/CRSBuilder.java | 29 ++++++++- .../org/apache/sis/storage/geotiff/GeoCodes.java | 15 ++++- .../apache/sis/storage/geotiff/GeoCodesTest.java | 68 ++++++++++++++++++++++ .../apache/sis/test/suite/GeoTiffTestSuite.java | 1 + 4 files changed, 109 insertions(+), 4 deletions(-) diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java index 58b39d3af4..cd2a2b459c 100644 --- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java +++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java @@ -63,6 +63,7 @@ import org.apache.sis.internal.referencing.WKTKeywords; import org.apache.sis.internal.referencing.NilReferencingObject; import org.apache.sis.internal.referencing.ReferencingUtilities; import org.apache.sis.internal.referencing.ReferencingFactoryContainer; +import org.apache.sis.internal.referencing.provider.PolarStereographicB; import org.apache.sis.internal.util.Constants; import org.apache.sis.internal.util.Strings; import org.apache.sis.internal.util.Numerics; @@ -88,7 +89,7 @@ import static org.apache.sis.util.Utilities.equalsIgnoreMetadata; * * @author Rémi Maréchal (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 1.2 + * @version 1.4 * * @see GeoKeys * @see GeoKeysLoader @@ -1253,6 +1254,29 @@ final class CRSBuilder extends ReferencingFactoryContainer { verify(projection, angularUnit, linearUnit); } + /** + * Returns the code of the operation method to request. + * This method tries to resolves some ambiguities in the way operation methods are defined. + * For example there is an ambiguity between Polar Stereographic (variant A) and (variant B). + */ + private String methodCode() { + final String code = getMandatoryString(GeoKeys.CoordTrans); + try { + switch (Integer.parseInt(code)) { + case GeoCodes.PolarStereographic: { + if (geoKeys.containsKey(GeoCodes.StdParallel1)) { + return Constants.EPSG + ':' + PolarStereographicB.IDENTIFIER; + } + break; + } + // More cases may be added in the future. + } + } catch (NumberFormatException e) { + return code; + } + return Constants.GEOTIFF + ':' + code; + } + /** * Creates a defining conversion from an EPSG code or from user-defined parameters. * @@ -1275,8 +1299,7 @@ final class CRSBuilder extends ReferencingFactoryContainer { } case GeoCodes.userDefined: { final Unit<Angle> azimuthUnit = createUnit(GeoKeys.AzimuthUnits, (short) 0, Angle.class, Units.DEGREE); - final String type = getMandatoryString(GeoKeys.CoordTrans); - final OperationMethod method = getCoordinateOperationFactory().getOperationMethod(Constants.GEOTIFF + ':' + type); + final OperationMethod method = getCoordinateOperationFactory().getOperationMethod(methodCode()); final ParameterValueGroup parameters = method.getParameters().createValue(); final Map<Integer,String> toNames = ReferencingUtilities.identifierToName(parameters.getDescriptor(), Citations.GEOTIFF); final Map<Object,Number> paramValues = new HashMap<>(); // Keys: [String|Short] instances for [known|unknown] parameters. diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoCodes.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoCodes.java index 79b7a003bd..43e188814e 100644 --- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoCodes.java +++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoCodes.java @@ -23,7 +23,7 @@ package org.apache.sis.storage.geotiff; * * @author Rémi Maréchal (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 1.0 + * @version 1.4 * @since 0.8 */ final class GeoCodes { @@ -81,4 +81,17 @@ final class GeoCodes { */ public static final short RasterPixelIsArea = 1; public static final short RasterPixelIsPoint = 2; + + /** + * The code for polar stereographic map projection. + * This is handled as a special case for distinguishing between variants. + */ + public static final short PolarStereographic = 15; + + /** + * The code for standard parallel map projection parameters. + * This is used as a sentinel value for distinguishing between + * different variants of a map projection. + */ + public static final short StdParallel1 = 3078; } diff --git a/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoCodesTest.java b/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoCodesTest.java new file mode 100644 index 0000000000..c97dd04686 --- /dev/null +++ b/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoCodesTest.java @@ -0,0 +1,68 @@ +/* + * 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.storage.geotiff; + +import org.opengis.util.FactoryException; +import org.opengis.parameter.ParameterDescriptorGroup; +import org.opengis.referencing.IdentifiedObject; +import org.opengis.referencing.operation.CoordinateOperationFactory; +import org.apache.sis.internal.system.DefaultFactories; +import org.apache.sis.metadata.iso.citation.Citations; +import org.apache.sis.referencing.IdentifiedObjects; +import org.apache.sis.test.TestCase; +import org.junit.Test; + +import static org.junit.Assert.*; + + +/** + * Verifies some {@link GeoCodes} values. + * + * @author Martin Desruisseaux (Geomatys) + * @version 1.4 + * @since 1.4 + */ +public final class GeoCodesTest extends TestCase { + /** + * Verifies the constants relative to the polar stereographic projection. + * + * @throws FactoryException if the operation method is not found. + */ + @Test + public void verifyPolarStereographic() throws FactoryException { + ParameterDescriptorGroup parameters = parameters("Polar Stereographic (Variant A)"); + assertEquals(GeoCodes.PolarStereographic, parseCode(parameters)); + + parameters = parameters("Polar Stereographic (Variant B)"); + assertEquals(GeoCodes.StdParallel1, parseCode(parameters.descriptor("Latitude of standard parallel"))); + } + + /** + * Returns the parameters for the operation method of the given name. + */ + private static ParameterDescriptorGroup parameters(final String method) throws FactoryException { + final CoordinateOperationFactory factory = DefaultFactories.forBuildin(CoordinateOperationFactory.class); + return factory.getOperationMethod(method).getParameters(); + } + + /** + * Returns the GeoTIFF code declared in the given object. + */ + private static int parseCode(final IdentifiedObject object) { + return Integer.parseInt(IdentifiedObjects.getIdentifier(object, Citations.GEOTIFF).getCode()); + } +} diff --git a/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java b/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java index 3432eaa123..7a84be4b32 100644 --- a/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java +++ b/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java @@ -35,6 +35,7 @@ import org.junit.BeforeClass; org.apache.sis.storage.geotiff.TypeTest.class, org.apache.sis.storage.geotiff.TagsTest.class, org.apache.sis.storage.geotiff.GeoKeysTest.class, + org.apache.sis.storage.geotiff.GeoCodesTest.class, org.apache.sis.storage.geotiff.CRSBuilderTest.class, org.apache.sis.storage.geotiff.XMLMetadataTest.class, org.apache.sis.storage.geotiff.SelfConsistencyTest.class