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 2017/07/22 18:39:58 UTC
svn commit: r1802708 - in /sis/branches/JDK8:
core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/
core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/
core/sis-referencing/src/test/java/org/apache/sis/referencing...
Author: desruisseaux
Date: Sat Jul 22 18:39:57 2017
New Revision: 1802708
URL: http://svn.apache.org/viewvc?rev=1802708&view=rev
Log:
Provide a plugin mechanism (SpecializedOperationFactory - may be renamed later) for enabling the use Proj.4 when we detect a pair of CRS that are wrappers around Proj.4.
Specifies axis units of measurement when creating a Proj.4 definition string from a CRS.
Improve documentation.
Added:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java (with props)
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java (with props)
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java (with props)
sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/
sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/
sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory (with props)
sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory (with props)
sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java (with props)
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
sis/branches/JDK8/ide-project/NetBeans/build.xml
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java
sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java
sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java
sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java
sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java
Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java?rev=1802708&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import java.util.Set;
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+
+
+/**
+ * Implemented by extension modules capable to provide coordinate operations for some particular pairs of CRS.
+ * Implementations of this interface are not general-purpose factories;
+ * they should not process any pair of CRS other than the one for which they are designed.
+ *
+ * <div class="note"><b>Example:</b>
+ * a module doing the bindings between Apache SIS and another map projection library may create wrappers
+ * around the transformation method of that other library when {@code findOperations(…)} recognizes the
+ * given CRS as wrappers around their data structures.</div>
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since 0.8
+ * @module
+ */
+public interface SpecializedOperationFactory {
+ /**
+ * Returns operations between the given pair of CRS, or an empty set if this factory does not recognize them.
+ * Non-empty sets have precedence over EPSG geodetic dataset or other mechanism used by Apache SIS, so should
+ * be used sparsely.
+ *
+ * @param sourceCRS the coordinate reference system of source points (before transformation).
+ * @param targetCRS the coordinate reference system of target points (after transformation).
+ * @return the coordinate operations from source to target CRS, or an empty set if this factory
+ * does not recognize the given pair of CRSs.
+ * @throws FactoryException if this factory recognizes the CRSs given in arguments,
+ * but an error occurred while creating the coordinate operation.
+ */
+ Set<CoordinateOperation> findOperations(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS)
+ throws FactoryException;
+}
Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -41,6 +41,7 @@ import org.apache.sis.internal.referenci
import org.apache.sis.internal.referencing.provider.GeographicToGeocentric;
import org.apache.sis.internal.referencing.provider.GeocentricToGeographic;
import org.apache.sis.internal.referencing.provider.GeocentricAffine;
+import org.apache.sis.internal.referencing.SpecializedOperationFactory;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.internal.util.Constants;
import org.apache.sis.measure.Units;
@@ -221,6 +222,17 @@ public class CoordinateOperationFinder e
throw new FactoryException(Resources.format(Resources.Keys.RecursiveCreateCallForCode_2, CoordinateOperation.class, key));
}
/*
+ * Verify if some extension module handles this pair of CRS in a special way. For example it may
+ * be the "sis-gdal" module checking if the given CRS are wrappers around Proj.4 data structure.
+ */
+ for (final SpecializedOperationFactory sp : factorySIS.getSpecializedFactories()) {
+ for (final CoordinateOperation op : sp.findOperations(sourceCRS, targetCRS)) {
+ if (filter(op)) {
+ return op;
+ }
+ }
+ }
+ /*
* If the user did not specified an area of interest, use the domain of validity of the CRS.
* Then verify in the EPSG dataset if the operation is explicitely defined by an authority.
*/
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -541,12 +541,19 @@ class CoordinateOperationRegistry {
* FactoryException propagate.
*/
bestChoice = complete(bestChoice, sourceCRS, targetCRS);
- if (filter == null || filter.test(bestChoice)) break;
+ if (filter(bestChoice)) break;
}
return bestChoice;
}
/**
+ * Returns {@code true} if the given operation can be accepted.
+ */
+ final boolean filter(final CoordinateOperation op) {
+ return filter == null || filter.test(op);
+ }
+
+ /**
* Creates the inverse of the given single operation.
* If this operation succeed, then the returned coordinate operations has the following properties:
*
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.List;
+import java.util.ServiceLoader;
import org.opengis.util.FactoryException;
import org.opengis.util.NoSuchIdentifierException;
import org.opengis.parameter.ParameterValueGroup;
@@ -36,10 +37,12 @@ import org.opengis.referencing.cs.CSFact
import org.opengis.referencing.datum.Datum;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.internal.referencing.MergedProperties;
+import org.apache.sis.internal.referencing.SpecializedOperationFactory;
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.util.LazySet;
import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
@@ -122,6 +125,17 @@ public class DefaultCoordinateOperationF
private volatile MathTransformFactory mtFactory;
/**
+ * Factories specialized to some particular pair of CRS. For example a module doing the bindings between
+ * Apache SIS and another map projection library may create wrappers around the transformation method of
+ * that other library when {@code SpecializedOperationFactory.tryCreateOperation(…)} recognizes the given
+ * CRS as wrappers around their data structures.
+ *
+ * <p>This array is created when first needed. After creation, the array shall not be modified anymore.</p>
+ */
+ @SuppressWarnings("VolatileArrayField")
+ private volatile SpecializedOperationFactory[] specializedFactories;
+
+ /**
* Weak references to existing objects.
* This set is used in order to return a pre-existing object instead of creating a new one.
* This applies to objects created explicitly, not to coordinate operations inferred by a
@@ -255,6 +269,20 @@ public class DefaultCoordinateOperationF
}
/**
+ * Returns all known factories specialized in the creation of coordinate operations between some particular
+ * pairs of CRS.
+ */
+ final SpecializedOperationFactory[] getSpecializedFactories() {
+ SpecializedOperationFactory[] factories = specializedFactories;
+ if (factories == null) {
+ final LazySet<SpecializedOperationFactory> set =
+ new LazySet<>(ServiceLoader.load(SpecializedOperationFactory.class).iterator());
+ specializedFactories = factories = set.toArray(new SpecializedOperationFactory[set.size()]);
+ }
+ return factories;
+ }
+
+ /**
* Returns the operation method of the given name. The given argument shall be either a method
* {@linkplain DefaultOperationMethod#getName() name} (e.g. <cite>"Transverse Mercator"</cite>)
* or one of its {@linkplain DefaultOperationMethod#getIdentifiers() identifiers} (e.g. {@code "EPSG:9807"}).
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -239,7 +239,7 @@ public final strictfp class EllipsoidToC
}
/**
- * Tests {@link EllipsoidToCentricTransform#concatenate(MathTransform, boolean, MathTransformFactory)}.
+ * Tests {@link EllipsoidToCentricTransform#tryConcatenate(boolean, MathTransform, MathTransformFactory)}.
* The test creates <cite>"Geographic 3D to 2D conversion"</cite>, <cite>"Geographic/Geocentric conversions"</cite>
* and <cite>"Geocentric translation"</cite> transforms, then concatenate them.
*
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -176,17 +176,17 @@ public class TableAppender extends Appen
private String lineSeparator;
/**
- * The column separator.
+ * The column separator, or an empty string if none.
*/
private final String columnSeparator;
/**
- * The left table border.
+ * The left table border, or an empty string if none.
*/
private final String leftBorder;
/**
- * The right table border.
+ * The right table border, or an empty string if none.
*/
private final String rightBorder;
Modified: sis/branches/JDK8/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/ide-project/NetBeans/build.xml?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/ide-project/NetBeans/build.xml (original)
+++ sis/branches/JDK8/ide-project/NetBeans/build.xml Sat Jul 22 18:39:57 2017
@@ -192,6 +192,13 @@
</fileset>
</concat>
+ <!-- SpecializedOperationFactory implementations to be loaded by ServiceLoader. -->
+ <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory" encoding="UTF-8" fixlastline="yes">
+ <fileset dir="${project.root}">
+ <include name="*/*/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory"/>
+ </fileset>
+ </concat>
+
<!-- DataStoreProvider implementations to be loaded by ServiceLoader. -->
<concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.storage.DataStoreProvider" encoding="UTF-8" fixlastline="yes">
<fileset dir="${project.root}">
Added: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java?rev=1802708&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java (added)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -0,0 +1,57 @@
+/*
+ * 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.storage.gdal;
+
+import java.util.Set;
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.apache.sis.internal.referencing.SpecializedOperationFactory;
+import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.storage.gdal.Proj4;
+
+
+/**
+ * The factory for operations between pair of {@literal Proj.4} wrappers.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since 0.8
+ * @module
+ */
+public final class OperationFactory implements SpecializedOperationFactory {
+ /**
+ * Creates a new factory.
+ */
+ public OperationFactory() {
+ }
+
+ /**
+ * Returns an operation between the given pair of CRS, or an empty set if this factory does not recognize
+ * the given CRSs.
+ *
+ * @return the coordinate operation, or an empty set if the given CRSs are not Proj.4 wrappers.
+ * @throws FactoryException if the given CRSs are Proj.4 wrappers and an error occurred while
+ * creating the coordinate operation.
+ */
+ @Override
+ public Set<CoordinateOperation> findOperations(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS)
+ throws FactoryException
+ {
+ return CollectionsExt.singletonOrEmpty(Proj4.createOperation(sourceCRS, targetCRS, false));
+ }
+}
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java?rev=1802708&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java (added)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Service providers for {@code sis-gdal} module.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since 0.8
+ * @module
+ */
+package org.apache.sis.internal.storage.gdal;
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -23,10 +23,12 @@ import org.opengis.util.FactoryException
import org.opengis.parameter.ParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.crs.GeodeticCRS;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.cs.CartesianCS;
@@ -36,8 +38,10 @@ import org.opengis.referencing.datum.Geo
import org.opengis.referencing.datum.PrimeMeridian;
import org.opengis.referencing.operation.Projection;
import org.opengis.referencing.operation.CoordinateOperation;
+import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
import org.apache.sis.referencing.factory.UnavailableFactoryException;
import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.CRS;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.internal.metadata.AxisDirections;
import org.apache.sis.internal.system.Modules;
@@ -46,6 +50,7 @@ import org.apache.sis.util.logging.Loggi
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.Static;
+import org.apache.sis.util.iso.Types;
import org.apache.sis.measure.Units;
@@ -98,6 +103,7 @@ public final class Proj4 extends Static
/**
* Infers a {@literal Proj.4} definition from the given projected, geographic or geocentric coordinate reference system.
* This method does not need the Proj.4 native library; it can be used in a pure Java application.
+ * However the returned definition string may differ depending on whether the Proj.4 library is available or not.
*
* @param crs the coordinate reference system for which to create a Proj.4 definition.
* @return the definition of the given CRS in a Proj.4 format.
@@ -154,21 +160,40 @@ public final class Proj4 extends Static
* Append the map projection parameters. Those parameters may include axis lengths (a and b),
* but not necessarily. If axis lengths are specified, then we will ignore the Ellipsoid instance
* associated to the CRS.
+ *
+ * The "+over" option is for disabling the default wrapping of output longitudes in the -180 to 180 range.
+ * We do that for having the same behavior between Proj.4 and Apache SIS. No wrapping reduce discontinuity
+ * problems with geometries that cross the anti-meridian.
+ *
+ * The "+no_defs" option is for ensuring that no defaults are read from "/usr/share/proj/proj_def.dat" file.
+ * That file contains default values for various map projections, for example "+lat_1=29.5" and "+lat_2=45.5"
+ * for the "aea" projection. Those defaults are assuming that users want Conterminous U.S. map.
+ * This may cause surprising behavior for users outside USA.
*/
final StringBuilder definition = new StringBuilder(100);
definition.append(Proj4Factory.PROJ_PARAM).append(method);
boolean hasSemiMajor = false;
boolean hasSemiMinor = false;
if (parameters != null) {
+ definition.append(" +over +no_defs"); // See above comment
for (final GeneralParameterValue parameter : parameters.values()) {
- if (parameter instanceof ParameterValue) {
- final Object value = ((ParameterValue) parameter).getValue();
- if (value != null) {
- final String pn = name(parameter.getDescriptor());
- if (pn.equals("+a")) hasSemiMajor = true;
- if (pn.equals("+b")) hasSemiMinor = true;
- definition.append(' ').append(pn).append('=').append(value);
+ if (parameter instanceof ParameterValue<?>) {
+ final ParameterValue<?> pv = (ParameterValue<?>) parameter;
+ final Object value;
+ Unit<?> unit = pv.getUnit();
+ if (unit != null) {
+ unit = Units.isAngular(unit) ? Units.DEGREE : unit.getSystemUnit();
+ value = pv.doubleValue(unit); // Always in metres or degrees.
+ } else {
+ value = pv.getValue();
+ if (value == null) {
+ continue;
+ }
}
+ final String pn = name(parameter.getDescriptor());
+ hasSemiMajor |= pn.equals("+a");
+ hasSemiMinor |= pn.equals("+b");
+ definition.append(' ').append(pn).append('=').append(value);
}
}
}
@@ -190,24 +215,59 @@ public final class Proj4 extends Static
/*
* Appends axis directions. This method always format a vertical direction (up or down)
* even if the coordinate system is two-dimensional, because Proj.4 seems to require it.
+ * Also extract axis units in the process.
*/
+ final Unit<?>[] units = new Unit<?>[2]; // Horizontal at index 0, vertical at index 1.
+ boolean validCS = true;
definition.append(' ').append(Proj4Factory.AXIS_ORDER_PARAM);
final int dimension = Math.min(cs.getDimension(), 3);
boolean hasVertical = false;
for (int i=0; i<dimension; i++) {
- final AxisDirection dir = cs.getAxis(i).getDirection();
+ final CoordinateSystemAxis axis = cs.getAxis(i);
+ final AxisDirection dir = axis.getDirection();
+ int unitIndex = 0;
if (!AxisDirections.isCardinal(dir)) {
if (!AxisDirections.isVertical(dir)) {
throw new FactoryException(Errors.format(Errors.Keys.UnsupportedAxisDirection_1, dir));
}
hasVertical = true;
+ unitIndex = 1;
}
+ final Unit<?> old = units[unitIndex];
+ units[unitIndex] = axis.getUnit();
+ validCS &= (old == null || old.equals(units[unitIndex]));
definition.appendCodePoint(Character.toLowerCase(dir.name().codePointAt(0)));
}
if (!hasVertical && dimension < 3) {
definition.append('u'); // Add a UP direction if not already present.
}
- return definition.toString();
+ /*
+ * Append units of measurement, then verify the coordinate system validity.
+ */
+ for (int i=0; i<units.length; i++) {
+ final Unit<?> unit = units[i];
+ if (unit != null && !unit.equals(Units.DEGREE) && !unit.equals(Units.METRE)) {
+ validCS &= Units.isLinear(unit);
+ definition.append(" +");
+ if (i == 1) definition.append('v'); // "+vto_meter" parameter.
+ definition.append("to_meter=").append(Units.toStandardUnit(unit));
+ }
+ }
+ if (validCS) {
+ return definition.toString();
+ }
+ /*
+ * If we reach this point, we detected a coordinate system that we can not format as a
+ * Proj.4 definition string. Format an error message with axis directions and units.
+ */
+ definition.setLength(0);
+ definition.append('(');
+ for (int i=0; i<units.length; i++) {
+ final CoordinateSystemAxis axis = cs.getAxis(i);
+ if (i != 0) definition.append(", ");
+ definition.append(axis.getUnit()).append(' ').append(Types.getCodeName(axis.getDirection()));
+ }
+ throw new FactoryException(Errors.format(Errors.Keys.IllegalCoordinateSystem_1, definition.append(')')));
}
/**
@@ -224,6 +284,16 @@ public final class Proj4 extends Static
/**
* Creates a new CRS from the given {@literal Proj.4} definition string.
+ * Some examples of definition strings are:
+ * <ul>
+ * <li>{@code "+init=epsg:3395"} (see warning below)</li>
+ * <li>{@code "+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"}</li>
+ * <li>{@code "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +ellps=WGS84 +towgs84=0,0,0"}</li>
+ * </ul>
+ *
+ * <b>Warning:</b> despite the {@code "epsg"} word, coordinate reference systems created by {@code "+init=epsg:"}
+ * syntax are not necessarily compliant with EPSG definitions. In particular, the axis order is often different.
+ * Units of measurement may also differ.
*
* @param definition the Proj.4 definition string.
* @param dimension the number of dimension of the CRS to create (2 or 3).
@@ -248,26 +318,49 @@ public final class Proj4 extends Static
/**
* Creates an operation for conversion or transformation between two coordinate reference systems.
- * This implementation always uses Proj.4 for performing the coordinate operations, regardless if
- * the given CRS were created from a Proj.4 definition string or not. This method fails if it can
- * not map the given CRS to Proj.4 structures.
- *
- * @param sourceCRS the source coordinate reference system.
- * @param targetCRS the target coordinate reference system.
- * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS.
- * @throws UnavailableFactoryException if the Proj.4 native library is not available.
- * @throws FactoryException if the operation creation failed for another reason.
+ * The given CRSs should be instances created by this package. If not, then there is a choice:
+ *
+ * <ul>
+ * <li>If {@code force} is {@code false}, then this method returns {@code null}.</li>
+ * <li>Otherwise this method always uses Proj.4 for performing the coordinate operations,
+ * regardless if the given CRS were created from Proj.4 definition strings or not.
+ * This method fails if it can not map the given CRS to Proj.4 data structures.</li>
+ * </ul>
+ *
+ * <p><b>Recommended alternative</b></p>
+ * Provided that an <a href="http://sis.apache.org/epsg.html">EPSG database is available</a>,
+ * Apache SIS {@link CRS#findOperation CRS.findOperation(…)} method produces results that are closer
+ * to the authoritative definitions of coordinate operations (technically, Apache SIS referencing
+ * engine is a <cite>late-binding</cite> implementation while Proj.4 is an <cite>early-binding</cite>
+ * implementation — see EPSG guidance notes for a definition of late versus early-binding approaches).
+ * Apache SIS also attaches metadata about
+ * {@linkplain AbstractCoordinateOperation#getCoordinateOperationAccuracy() coordinate operation accuracy} and
+ * {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity}, have extended support of
+ * multi-dimensional CRS and provides transform derivatives. This {@code Proj4.createOperation(…)} method should
+ * be reserved to situations where an application needs to reproduce the same numerical results than Proj.4.
+ *
+ * @param sourceCRS the source coordinate reference system.
+ * @param targetCRS the target coordinate reference system.
+ * @param force whether to force the creation of a Proj.4 transform
+ * even if the given CRS are not wrappers around Proj.4 data structures.
+ * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS, or
+ * {@code null} if the given CRS are not wrappers around Proj.4 data structures and {@code force} is false.
+ * @throws UnavailableFactoryException if {@code force} is {@code true} and the Proj.4 native library is not available.
+ * @throws FactoryException if {@code force} is {@code true} and this method can not create Proj.4 transform
+ * for the given pair of coordinate reference systems for another reason.
*
- * @see Proj4Factory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)
+ * @see Proj4Factory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
+ * @see CRS#findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox)
*/
public static CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
- final CoordinateReferenceSystem targetCRS)
+ final CoordinateReferenceSystem targetCRS,
+ final boolean force)
throws FactoryException
{
ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
try {
- return Proj4Factory.INSTANCE.createOperation(sourceCRS, targetCRS);
+ return Proj4Factory.INSTANCE.createOperation(sourceCRS, targetCRS, force);
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
throw new UnavailableFactoryException(unavailable(), e);
}
Modified: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -38,6 +38,7 @@ import org.apache.sis.referencing.Identi
import org.apache.sis.referencing.operation.DefaultConversion;
import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
+import org.apache.sis.referencing.factory.UnavailableFactoryException;
import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.internal.util.Constants;
@@ -65,7 +66,7 @@ import org.apache.sis.measure.Units;
* <ul>
* <li>{@link #getAuthority()}</li>
* <li>{@link #createCoordinateReferenceSystem(String)}</li>
- * <li>{@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)}</li>
+ * <li>{@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)}</li>
* <li>{@link #createParameterizedTransform(ParameterValueGroup)}</li>
* </ul>
*
@@ -101,7 +102,7 @@ public class Proj4Factory extends Geodet
/**
* The default factory instance.
*/
- static final Proj4Factory INSTANCE = new Proj4Factory(null);
+ static final Proj4Factory INSTANCE = new Proj4Factory();
/**
* The default properties, or an empty map if none. This map shall not change after construction in
@@ -152,6 +153,13 @@ public class Proj4Factory extends Geodet
private final WeakValueHashMap<String,PJ> pool = new WeakValueHashMap<>(String.class);
/**
+ * Creates a default factory.
+ */
+ public Proj4Factory() {
+ this(null);
+ }
+
+ /**
* Creates a new {@literal Proj.4} factory. The {@code properties} argument is an optional map
* for specifying common properties shared by the objects to create. Some available properties are
* {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#AbstractIdentifiedObject(Map) listed there}.
@@ -473,7 +481,11 @@ public class Proj4Factory extends Geodet
}
}
}
- return createCRS(code, hasHeight);
+ try {
+ return createCRS(code, hasHeight);
+ } catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
+ throw new UnavailableFactoryException(Proj4.unavailable(), e);
+ }
}
/**
@@ -625,16 +637,17 @@ public class Proj4Factory extends Geodet
/**
* Gets the {@literal Proj.4} object from the given coordinate reference system. If an existing {@code PJ}
- * instance is found, returns it. Otherwise creates a new {@code PJ} instance from a Proj.4 definition
- * inferred from the given CRS. This method is the converse of {@link #createCRS(PJ, boolean)}.
+ * instance is found, returns it. Otherwise if {@code force} is {@code true}, creates a new {@code PJ}
+ * instance from a Proj.4 definition inferred from the given CRS.
+ * This method is the converse of {@link #createCRS(PJ, boolean)}.
*/
- private PJ unwrapOrCreate(final CoordinateReferenceSystem crs) throws FactoryException {
+ private PJ unwrapOrCreate(final CoordinateReferenceSystem crs, final boolean force) throws FactoryException {
for (final Identifier id : crs.getIdentifiers()) {
if (id instanceof PJ) {
return (PJ) id;
}
}
- return unique(new PJ(Proj4.definition(crs)));
+ return force ? unique(new PJ(Proj4.definition(crs))) : null;
}
/**
@@ -671,22 +684,57 @@ public class Proj4Factory extends Geodet
/**
* Creates an operation for conversion or transformation between two coordinate reference systems.
- * This implementation always uses Proj.4 for performing the coordinate operations, regardless if
- * the given CRS were created from a Proj.4 definition string or not. This method fails if it can
- * not map the given CRS to Proj.4 structures.
+ * The given CRSs should be instances {@linkplain #createCoordinateReferenceSystem created by this factory}.
+ * If not, then there is a choice:
+ *
+ * <ul>
+ * <li>If {@code force} is {@code false}, then this method returns {@code null}.</li>
+ * <li>Otherwise this method always uses Proj.4 for performing the coordinate operations,
+ * regardless if the given CRS were created from Proj.4 definition strings or not.
+ * This method fails if it can not map the given CRS to Proj.4 data structures.</li>
+ * </ul>
*
* @param sourceCRS the source coordinate reference system.
* @param targetCRS the target coordinate reference system.
- * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS.
- * @throws FactoryException if the given CRS are not instances recognized by this class.
+ * @param force whether to force the creation of a Proj.4 transform
+ * even if the given CRS are not wrappers around Proj.4 data structures.
+ * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS, or
+ * {@code null} if the given CRS are not wrappers around Proj.4 data structures and {@code force} is false.
+ * @throws FactoryException if {@code force} is {@code true} and this method can not create Proj.4 transform
+ * for the given pair of coordinate reference systems.
*
- * @see Proj4#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)
+ * @see Proj4#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
* @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)
*/
public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
- final CoordinateReferenceSystem targetCRS)
+ final CoordinateReferenceSystem targetCRS,
+ final boolean force)
throws FactoryException
{
+ final PJ source, target;
+ if ((source = unwrapOrCreate(sourceCRS, force)) == null ||
+ (target = unwrapOrCreate(targetCRS, force)) == null)
+ {
+ return null; // At least one CRS is not a Proj.4 wrapper and 'force' is false.
+ }
+ /*
+ * Before to create a transform, verify if the target CRS already contains a suitable transform.
+ * In such case, returning the existing operation is preferable since it usually contains better
+ * parameter description than what this method build.
+ */
+ if (targetCRS instanceof GeneralDerivedCRS) {
+ final CoordinateOperation op = ((GeneralDerivedCRS) targetCRS).getConversionFromBase();
+ final MathTransform tr = op.getMathTransform();
+ if (tr instanceof Transform && ((Transform) tr).isFor(sourceCRS, source, targetCRS, target)) {
+ return op;
+ }
+ }
+ /*
+ * The 'Transform' construction implies parameter validation, so we do it first before to
+ * construct other objects.
+ */
+ final Transform tr = new Transform(source, is3D("sourceCRS", sourceCRS),
+ target, is3D("targetCRS", targetCRS));
Identifier id;
String src = null, tgt = null, name = "Unnamed";
if ((id = sourceCRS.getName()) != null) src = id.getCode();
@@ -697,8 +745,6 @@ public class Proj4Factory extends Geodet
if (tgt != null) buffer.append(buffer.length() == 0 ? "To " : " to ").append(tgt);
name = buffer.toString();
}
- final Transform tr = new Transform(unwrapOrCreate(sourceCRS), is3D("sourceCRS", sourceCRS),
- unwrapOrCreate(targetCRS), is3D("targetCRS", targetCRS));
return opFactory().createSingleOperation(identifier(name), sourceCRS, targetCRS, null, Transform.METHOD, tr);
}
Modified: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -18,6 +18,7 @@ package org.apache.sis.storage.gdal;
import java.io.Serializable;
import java.util.Collections;
+import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
@@ -26,12 +27,13 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.internal.util.Constants;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.parameter.ParameterBuilder;
import org.apache.sis.referencing.operation.DefaultOperationMethod;
import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
-import org.opengis.util.FactoryException;
+import org.apache.sis.util.ComparisonMode;
/**
@@ -196,4 +198,43 @@ final class Transform extends AbstractMa
}
return super.tryConcatenate(applyOtherFirst, other, factory);
}
+
+ /**
+ * Returns {@code true} if this math transform is for the given pair of source and target CRS.
+ */
+ final boolean isFor(final CoordinateReferenceSystem sourceCRS, final PJ sourcePJ,
+ final CoordinateReferenceSystem targetCRS, final PJ targetPJ)
+ {
+ return source.equals(sourcePJ) && dimensionMatches(sourceCRS, source3D) &&
+ target.equals(targetPJ) && dimensionMatches(targetCRS, target3D);
+ }
+
+ /**
+ * Tests whether the given CRS matches the expected number of dimensions.
+ */
+ private static boolean dimensionMatches(final CoordinateReferenceSystem crs, final boolean is3D) {
+ return crs.getCoordinateSystem().getDimension() == (is3D ? 3 : 2);
+ }
+
+ /**
+ * Computes a hash value for this transform. This method is invoked by {@link #hashCode()} when first needed.
+ */
+ @Override
+ protected int computeHashCode() {
+ return super.computeHashCode() + source.hashCode() + 31*target.hashCode();
+ }
+
+ /**
+ * Compares the given object with this transform for equality.
+ * This implementation can not ignore metadata or rounding errors.
+ */
+ @Override
+ public boolean equals(final Object object, final ComparisonMode mode) {
+ if (object instanceof Transform) {
+ final Transform that = (Transform) object;
+ return source.equals(that.source) && source3D == that.source3D
+ && target.equals(that.target) && target3D == that.target3D;
+ }
+ return false;
+ }
}
Modified: sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -16,9 +16,10 @@
*/
/**
- * Referencing services as wrapper around the C/C++ <a href="http://proj.osgeo.org/">{@literal Proj.4}</a> library.
- * Unless otherwise specified, this optional module requires the native (C/C++) Proj.4 library to be installed
- * on the local machine. This package allows to:
+ * Referencing services as wrapper around the C/C++ {@literal Proj.4} library.
+ * Current version wraps only referencing services, but future versions are expected to wrap more GDAL functionalities.
+ * Unless otherwise specified, this optional module requires the native (C/C++) <a href="http://proj.osgeo.org/">Proj.4</a>
+ * library to be installed on the local machine. This package allows to:
* <ul>
* <li>{@linkplain org.apache.sis.storage.gdal.Proj4#createCRS Create a Coordinate Reference System instance from a Proj.4 definition string}.</li>
* <li>Conversely, {@linkplain org.apache.sis.storage.gdal.Proj4#definition get a Proj.4 definition string from a Coordinate Reference System}.</li>
@@ -26,17 +27,41 @@
* </ul>
*
* Note that Apache SIS provides its own map projection engine in pure Java, so this module is usually not needed.
- * This module is useful when a desired map projection is not yet available in Apache SIS, or when an application
- * needs to reproduce the exact same numerical results than Proj.4. But some Apache SIS features like
+ * This module is useful when a map projection is not yet available in Apache SIS, or when an application needs to
+ * reproduce the exact same numerical results than Proj.4. But some Apache SIS features like
* {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#derivative transform derivatives}
* are not available through the Proj.4 wrappers.
*
+ * <div class="section">Note on Proj.4 definition strings</div>
+ * Proj.4 unconditionally requires 3 letters for the {@code "+axis="} parameter — for example {@code "neu"} for
+ * <cite>North</cite>, <cite>East</cite> and <cite>Up</cite> respectively — regardless the number of dimensions
+ * in the CRS to create. Apache SIS makes the vertical direction optional in order to specify whether the CRS to
+ * create shall contain a vertical axis or not:
+ *
+ * <ul>
+ * <li>If the vertical direction is present (as in {@code "neu"}), a three-dimensional CRS is created.</li>
+ * <li>If the vertical direction is absent (as in {@code "ne"}), a two-dimensional CRS is created.</li>
+ * </ul>
+ *
+ * <div class="note"><b>Examples:</b>
+ * <ul>
+ * <li>{@code "+init=epsg:4326"} (<strong>not</strong> equivalent to the standard EPSG::4326 definition)</li>
+ * <li>{@code "+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"} (default to two-dimensional CRS)</li>
+ * <li>{@code "+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=ne"} (explicitely two-dimensional)</li>
+ * <li>{@code "+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=neu"} (three-dimensional)</li>
+ * </ul>
+ * </div>
+ *
+ * <b>Warning:</b> despite the {@code "epsg"} word, coordinate reference systems created by {@code "+init=epsg:"}
+ * syntax are not necessarily compliant with EPSG definitions. In particular, the axis order is often different.
+ * Units of measurement may also differ.
+ *
* <div class="section">Installation</div>
* The Proj.4 library needs to be reachable on a platform-dependent library path.
- * For example the operating system may search in the {@code /opt/local/lib} and other directories.
- * One of those directories shall contain a {@code libproj.so}, {@code libproj.dylib} or {@code proj.dll} file,
- * depending on the platform. An easy way to install the library in appropriate directory is to use the package
- * manager provided by the platform.
+ * For example the operating system may search in {@code /usr/lib}, {@code /opt/local/lib} and other directories.
+ * One of those directories shall contain the {@code proj} or {@code libproj} file with platform-specific suffix
+ * (e.g. {@code .so}, {@code .dylib} or {@code .dll}).
+ * An easy way to install the library in appropriate directory is to use the package manager provided by the platform.
*
* @author Martin Desruisseaux (Geomatys)
* @version 0.8
Added: sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory?rev=1802708&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory (added)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory [UTF-8] Sat Jul 22 18:39:57 2017
@@ -0,0 +1 @@
+org.apache.sis.internal.storage.gdal.OperationFactory
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory?rev=1802708&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory (added)
+++ sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory [UTF-8] Sat Jul 22 18:39:57 2017
@@ -0,0 +1 @@
+org.apache.sis.storage.gdal.Proj4Factory
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added: sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java?rev=1802708&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java (added)
+++ sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -0,0 +1,54 @@
+/*
+ * 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.gdal;
+
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+import org.opengis.referencing.operation.TransformException;
+
+import static org.opengis.test.Assert.*;
+
+
+/**
+ * Tests the integration of the {@code sis-gdal} module in the Apache SIS framework.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since 0.8
+ * @module
+ */
+public final strictfp class IntegrationTest extends TestCase {
+ /**
+ * Tests usage of {@link CRS#forCode(String)}.
+ *
+ * @throws FactoryException if the coordinate reference system can not be created.
+ * @throws TransformException if an error occurred while testing a coordinate transformation.
+ */
+ @Test
+ @org.junit.Ignore
+ public void testCRS() throws FactoryException, TransformException {
+ final CoordinateReferenceSystem sourceCRS = CRS.forCode("Proj4:+init=epsg:4326");
+ final CoordinateReferenceSystem targetCRS = CRS.forCode("Proj4:+init=epsg:3395");
+ final CoordinateOperation op = CRS.findOperation(sourceCRS, targetCRS, null);
+ assertInstanceOf("Expected Proj.4 wrapper.", Transform.class, op.getMathTransform());
+ Proj4FactoryTest.testMercatorProjection(op.getMathTransform());
+ }
+}
Propchange: sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -75,6 +75,27 @@ class MTFactory extends Proj4Factory imp
}
/**
+ * Creates an operation for conversion or transformation between two coordinate reference systems.
+ * This implementation always uses Proj.4 for performing the coordinate operations, regardless if
+ * the given CRS were created from Proj.4 definition strings or not. This method fails if it can
+ * not map the given CRS to Proj.4 data structures.
+ *
+ * @param sourceCRS the source coordinate reference system.
+ * @param targetCRS the target coordinate reference system.
+ * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS.
+ * @throws FactoryException if the given CRS are not instances recognized by this class.
+ *
+ * @see Proj4#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
+ */
+ @Override
+ public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
+ final CoordinateReferenceSystem targetCRS)
+ throws FactoryException
+ {
+ return createOperation(sourceCRS, targetCRS, true);
+ }
+
+ /**
* Ignores the given {@code method} argument and delegates to
* <code>{@linkplain #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)
* createOperation}(sourceCRS, targetCRS)</code>.
Modified: sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -113,7 +113,7 @@ public final strictfp class Proj4Factory
final Proj4Factory factory = Proj4Factory.INSTANCE;
final GeographicCRS sourceCRS = factory.createGeographicCRS("+init=epsg:4326");
final ProjectedCRS targetCRS = factory.createProjectedCRS("+init=epsg:3395");
- final CoordinateOperation op = factory.createOperation(sourceCRS, targetCRS);
+ final CoordinateOperation op = factory.createOperation(sourceCRS, targetCRS, true);
assertInstanceOf("createOperation", Conversion.class, op);
testMercatorProjection(op.getMathTransform());
}
@@ -121,7 +121,7 @@ public final strictfp class Proj4Factory
/**
* Tests EPSG:3395 on a point.
*/
- private static void testMercatorProjection(final MathTransform mt) throws TransformException {
+ static void testMercatorProjection(final MathTransform mt) throws TransformException {
DirectPosition pt = new DirectPosition2D(20, 40);
pt = mt.transform(pt, pt);
assertEquals("Easting", 2226389.816, pt.getOrdinate(0), 0.01);
Modified: sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java?rev=1802708&r1=1802707&r2=1802708&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java [UTF-8] Sat Jul 22 18:39:57 2017
@@ -34,7 +34,8 @@ import org.junit.runners.Suite;
org.apache.sis.storage.gdal.Proj4Test.class,
org.apache.sis.storage.gdal.Proj4ParserTest.class,
org.apache.sis.storage.gdal.Proj4FactoryTest.class,
- org.apache.sis.storage.gdal.TransformTest.class
+ org.apache.sis.storage.gdal.TransformTest.class,
+ org.apache.sis.storage.gdal.IntegrationTest.class
})
public final strictfp class GDALTestSuite extends TestSuite {
/**