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 2019/06/21 15:48:23 UTC

[sis] 10/10: EllipsoidalHeightCombiner leverage ReferencingFactoryContainer. https://issues.apache.org/jira/browse/SIS-463

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 59a23685545dcf5aac04f369eb3c5cb3731f326a
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Jun 21 17:41:30 2019 +0200

    EllipsoidalHeightCombiner leverage ReferencingFactoryContainer.
    https://issues.apache.org/jira/browse/SIS-463
---
 .../referencing/EllipsoidalHeightCombiner.java     | 60 ++++++----------------
 .../referencing/GeodeticObjectBuilder.java         |  8 +--
 .../referencing/ReferencingFactoryContainer.java   | 32 +++++++++++-
 .../main/java/org/apache/sis/referencing/CRS.java  | 10 +---
 .../referencing/operation/CompoundCRSBuilder.java  | 57 --------------------
 .../operation/CoordinateOperationFinder.java       |  5 +-
 .../operation/CoordinateOperationRegistry.java     |  5 +-
 .../referencing/EllipsoidalHeightCombinerTest.java |  8 +--
 8 files changed, 57 insertions(+), 128 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombiner.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombiner.java
index 96cfdd7..0f90726 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombiner.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombiner.java
@@ -53,32 +53,20 @@ import org.apache.sis.util.ArraysExt;
  * @since 0.8
  * @module
  */
-public class EllipsoidalHeightCombiner {
+public final class EllipsoidalHeightCombiner extends ReferencingFactoryContainer {
     /**
-     * The kind of factory initialized by {@link #initialize(int)}.
-     */
-    protected static final int CRS=1, CS=2, OPERATION=4;
-
-    /**
-     * The factory to use for creating compound or three-dimensional geographic CRS.
-     */
-    protected CRSFactory crsFactory;
-
-    /**
-     * The factory to use for creating three-dimensional ellipsoidal CS, if needed.
-     */
-    protected CSFactory csFactory;
-
-    /**
-     * The factory to use for creating defining conversions, if needed.
+     * Creates a new combiner with no initial factory.
      */
-    protected CoordinateOperationFactory opFactory;
+    public EllipsoidalHeightCombiner() {
+    }
 
     /**
-     * Creates a new combiner with no initial factory.
-     * Subclasses must override the {@link #initialize(int)} method.
+     * Creates a new instance initialized to the factories of the given container.
+     *
+     * @param  c  the container from which to fetch the factories.
      */
-    protected EllipsoidalHeightCombiner() {
+    protected EllipsoidalHeightCombiner(final ReferencingFactoryContainer c) {
+        super(c);
     }
 
     /**
@@ -92,20 +80,7 @@ public class EllipsoidalHeightCombiner {
     public EllipsoidalHeightCombiner(final CRSFactory crsFactory, final CSFactory csFactory,
                                      final CoordinateOperationFactory opFactory)
     {
-        this.crsFactory = crsFactory;
-        this.csFactory  = csFactory;
-        this.opFactory  = opFactory;
-    }
-
-    /**
-     * Initializes the factory identified by the given code. This is used for lazy initialization if any factory given
-     * to the constructor was null. In such case, subclass must override. If the same {@code EllipsoidalHeightCombiner}
-     * instance is used more than once, than it is subclass responsibility to verify that the {@link #crsFactory},
-     * {@link #csFactory} or {@link #opFactory} field has not already been set.
-     *
-     * @param  factoryTypes  a bitwise combination of {@link #CRS}, {@link #CS} and {@link #OPERATION}.
-     */
-    protected void initialize(final int factoryTypes) {
+        super(crsFactory, csFactory, opFactory);
     }
 
     /**
@@ -164,11 +139,9 @@ public class EllipsoidalHeightCombiner {
                     final Map<String,?> crsProps = (components.length == 2) ? properties
                                                    : IdentifiedObjects.getProperties(crs, CoordinateReferenceSystem.IDENTIFIERS_KEY);
                     if (crs instanceof GeodeticCRS) {
-                        initialize(CS | CRS);
-                        cs = csFactory.createEllipsoidalCS(csProps, axes[0], axes[1], axes[2]);
-                        crs = crsFactory.createGeographicCRS(crsProps, ((GeodeticCRS) crs).getDatum(), (EllipsoidalCS) cs);
+                        cs = getCSFactory().createEllipsoidalCS(csProps, axes[0], axes[1], axes[2]);
+                        crs = getCRSFactory().createGeographicCRS(crsProps, ((GeodeticCRS) crs).getDatum(), (EllipsoidalCS) cs);
                     } else {
-                        initialize(CS | CRS | OPERATION);
                         final ProjectedCRS proj = (ProjectedCRS) crs;
                         GeographicCRS base = proj.getBaseCRS();
                         if (base.getCoordinateSystem().getDimension() == 2) {
@@ -181,10 +154,11 @@ public class EllipsoidalHeightCombiner {
                          * for letting SIS create or associate new ones, which will be three-dimensional now.
                          */
                         Conversion fromBase = proj.getConversionFromBase();
-                        fromBase = opFactory.createDefiningConversion(IdentifiedObjects.getProperties(fromBase),
+                        fromBase = getCoordinateOperationFactory().createDefiningConversion(
+                                    IdentifiedObjects.getProperties(fromBase),
                                     fromBase.getMethod(), fromBase.getParameterValues());
-                        cs = csFactory.createCartesianCS(csProps, axes[0], axes[1], axes[2]);
-                        crs = crsFactory.createProjectedCRS(crsProps, base, fromBase, (CartesianCS) cs);
+                        cs = getCSFactory().createCartesianCS(csProps, axes[0], axes[1], axes[2]);
+                        crs = getCRSFactory().createProjectedCRS(crsProps, base, fromBase, (CartesianCS) cs);
                     }
                     /*
                      * Remove the VerticalCRS and store the three-dimensional GeographicCRS in place of the previous
@@ -200,7 +174,7 @@ public class EllipsoidalHeightCombiner {
         switch (components.length) {
             case 0:  return null;
             case 1:  return components[0];
-            default: initialize(CRS); return crsFactory.createCompoundCRS(properties, components);
+            default: return getCRSFactory().createCompoundCRS(properties, components);
         }
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
index 74c24cd..683a1ca 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
@@ -508,13 +508,7 @@ public final class GeodeticObjectBuilder extends Builder<GeodeticObjectBuilder>
      * @throws FactoryException if the object creation failed.
      */
     public CoordinateReferenceSystem createCompoundCRS(final CoordinateReferenceSystem... components) throws FactoryException {
-        return new EllipsoidalHeightCombiner() {
-            @Override public void initialize(final int factoryTypes) {
-                if ((factoryTypes & CRS)       != 0) crsFactory = factories.getCRSFactory();
-                if ((factoryTypes & CS)        != 0)  csFactory = factories.getCSFactory();
-                if ((factoryTypes & OPERATION) != 0)  opFactory = factories.getCoordinateOperationFactory();
-            }
-        }.createCompoundCRS(properties, components);
+        return new EllipsoidalHeightCombiner(factories).createCompoundCRS(properties, components);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingFactoryContainer.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingFactoryContainer.java
index 3a3e6a7..d495833 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingFactoryContainer.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingFactoryContainer.java
@@ -28,9 +28,9 @@ import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.CoordinateOperationFactory;
 import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
 import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
+import org.apache.sis.referencing.CRS;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.Constants;
-import org.apache.sis.referencing.CRS;
 
 
 /**
@@ -116,6 +116,36 @@ public class ReferencingFactoryContainer {
     }
 
     /**
+     * Creates a new instance initialized to the factories of the given container.
+     *
+     * @param  c  the container from which to fetch the factories.
+     */
+    protected ReferencingFactoryContainer(final ReferencingFactoryContainer c) {
+        crsAuthorityFactory = c.crsAuthorityFactory;
+        datumFactory        = c.datumFactory;
+        csFactory           = c.csFactory;
+        crsFactory          = c.crsFactory;
+        operationFactory    = c.operationFactory;
+        mtFactory           = c.mtFactory;
+    }
+
+    /**
+     * Creates a new instance which will use the given factories.
+     * Any factory given in argument may be {@code null} if lazy instantiation is desired.
+     *
+     * @param  crsFactory        the factory to use for creating compound or three-dimensional geographic CRS.
+     * @param  csFactory         the factory to use for creating three-dimensional ellipsoidal CS, if needed.
+     * @param  operationFactory  the factory to use for creating defining conversions, if needed.
+     */
+    protected ReferencingFactoryContainer(final CRSFactory crsFactory, final CSFactory csFactory,
+                                          final CoordinateOperationFactory operationFactory)
+    {
+        this.crsFactory       = crsFactory;
+        this.csFactory        = csFactory;
+        this.operationFactory = operationFactory;
+    }
+
+    /**
      * Returns the factory for creating coordinate reference systems from authority codes.
      * Currently only EPSG codes are supported.
      *
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index 8953954..1b9b49d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@ -30,7 +30,6 @@ import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
-import org.opengis.referencing.cs.CSFactory;
 import org.opengis.referencing.crs.CRSFactory;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.CompoundCRS;
@@ -46,7 +45,6 @@ import org.opengis.referencing.crs.EngineeringCRS;
 import org.opengis.referencing.datum.Datum;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.Conversion;
-import org.opengis.referencing.operation.CoordinateOperationFactory;
 import org.opengis.referencing.operation.OperationNotFoundException;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.extent.Extent;
@@ -921,13 +919,7 @@ public final class CRS extends Static {
                 break;
             }
         }
-        return new EllipsoidalHeightCombiner() {
-            @Override public void initialize(final int factoryTypes) {
-                if ((factoryTypes & CRS)       != 0) crsFactory = DefaultFactories.forBuildin(CRSFactory.class);
-                if ((factoryTypes & CS)        != 0) csFactory  = DefaultFactories.forBuildin(CSFactory.class);
-                if ((factoryTypes & OPERATION) != 0) opFactory  = DefaultFactories.forBuildin(CoordinateOperationFactory.class);
-            }
-        }.createCompoundCRS(components);
+        return new EllipsoidalHeightCombiner().createCompoundCRS(components);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java
deleted file mode 100644
index d9b2062..0000000
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.referencing.operation;
-
-import org.apache.sis.internal.referencing.EllipsoidalHeightCombiner;
-import org.opengis.referencing.operation.CoordinateOperationFactory;
-
-
-/**
- * Helper class for combining two-dimensional geographic or projected CRS with an ellipsoidal height
- * into a three-dimensional CRS.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-final class CompoundCRSBuilder extends EllipsoidalHeightCombiner {
-    /**
-     * The Apache SIS implementation of {@link CoordinateOperationFactory}.
-     */
-    private final DefaultCoordinateOperationFactory factorySIS;
-
-    /**
-     * Creates a new builder for the given coordinate operation factory.
-     *
-     * @param factory     the factory to use for creating coordinate operations.
-     * @param factorySIS  used only when we need a SIS-specific method.
-     */
-    CompoundCRSBuilder(final CoordinateOperationFactory factory, final DefaultCoordinateOperationFactory factorySIS) {
-        super(null, null, factory);
-        this.factorySIS = factorySIS;
-    }
-
-    /**
-     * Invoked when the builder needs a CRS or CS factory.
-     */
-    @Override
-    public void initialize(final int factoryTypes) {
-        if ((factoryTypes & CRS) != 0) crsFactory = factorySIS.getCRSFactory();
-        if ((factoryTypes & CS)  != 0)  csFactory = factorySIS.getCSFactory();
-    }
-}
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
index dd8aa01..79bbbbc 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
@@ -37,6 +37,7 @@ import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.internal.referencing.CoordinateOperations;
+import org.apache.sis.internal.referencing.EllipsoidalHeightCombiner;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.provider.Affine;
 import org.apache.sis.internal.referencing.provider.DatumShiftMethod;
@@ -970,8 +971,8 @@ public class CoordinateOperationFinder extends CoordinateOperationRegistry {
             } else if (stepComponents.length == 1) {
                 stepTargetCRS = target;                 // Slight optimization of the next block.
             } else {
-                stepTargetCRS = toAuthorityDefinition(CoordinateReferenceSystem.class,
-                        new CompoundCRSBuilder(factory, factorySIS).createCompoundCRS(derivedFrom(target), stepComponents));
+                final EllipsoidalHeightCombiner c = new EllipsoidalHeightCombiner(factorySIS.getCRSFactory(), factorySIS.getCSFactory(), factory);
+                stepTargetCRS = toAuthorityDefinition(CoordinateReferenceSystem.class, c.createCompoundCRS(derivedFrom(target), stepComponents));
             }
             int delta = source.getCoordinateSystem().getDimension();
             final int startAtDimension = endAtDimension;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
index a11b64e..91feda4 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
@@ -62,6 +62,7 @@ import org.apache.sis.metadata.iso.extent.Extents;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.internal.referencing.CoordinateOperations;
 import org.apache.sis.internal.referencing.DeferredCoordinateOperation;
+import org.apache.sis.internal.referencing.EllipsoidalHeightCombiner;
 import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.provider.Affine;
@@ -1024,8 +1025,8 @@ class CoordinateOperationRegistry {
                 return candidate;               // Keep the existing instance since it may contain useful metadata.
             }
         }
-        return toAuthorityDefinition(CoordinateReferenceSystem.class,
-                new CompoundCRSBuilder(factory, factorySIS).createCompoundCRS(derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs()));
+        final EllipsoidalHeightCombiner c = new EllipsoidalHeightCombiner(factorySIS.getCRSFactory(), factorySIS.getCSFactory(), factory);
+        return toAuthorityDefinition(CoordinateReferenceSystem.class, c.createCompoundCRS(derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs()));
     }
 
     /**
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombinerTest.java b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombinerTest.java
index 2666dec..a71c9fa 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombinerTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/EllipsoidalHeightCombinerTest.java
@@ -62,13 +62,7 @@ public final strictfp class EllipsoidalHeightCombinerTest extends TestCase {
      */
     private static EllipsoidalHeightCombiner create() {
         final GeodeticObjectFactory factory = new GeodeticObjectFactory();
-        return new EllipsoidalHeightCombiner(factory, factory, null) {
-            @Override protected void initialize(final int factoryTypes) {
-                if ((factoryTypes & OPERATION) != 0) {
-                    opFactory = new DefaultCoordinateOperationFactory();
-                }
-            }
-        };
+        return new EllipsoidalHeightCombiner(factory, factory, new DefaultCoordinateOperationFactory());
     }
 
     /**