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/01/08 19:59:19 UTC
[sis] 01/02: Move JTS specific methods to "jts" subpackage.
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 e891f327a4dcef7f5c9ce97a9a17627085230fa2
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Jan 8 20:48:43 2019 +0100
Move JTS specific methods to "jts" subpackage.
---
.../apache/sis/internal/feature/Geometries.java | 52 ++-----
.../java/org/apache/sis/internal/feature/JTS.java | 158 ++-------------------
.../feature/jts/GeometryCoordinateTransform.java | 14 +-
.../internal/feature/jts/GeometryTransform.java | 77 +++++-----
.../org/apache/sis/internal/feature/jts/JTS.java | 156 ++++++++++++++++++++
.../sis/internal/feature/jts/package-info.java | 31 ++++
.../sis/internal/feature/GeometriesTestCase.java | 2 +-
.../org/apache/sis/internal/feature/JTSTest.java | 71 ---------
.../sis/internal/feature/{ => jts}/JTSTest.java | 71 ++-------
.../apache/sis/test/suite/FeatureTestSuite.java | 1 +
10 files changed, 268 insertions(+), 365 deletions(-)
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
index 0d6beae..0c83667 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
@@ -19,8 +19,6 @@ package org.apache.sis.internal.feature;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.LogRecord;
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.internal.system.Loggers;
import org.apache.sis.geometry.GeneralEnvelope;
@@ -107,7 +105,7 @@ public abstract class Geometries<G> {
String classname = Geometries.class.getName();
classname = classname.substring(0, classname.lastIndexOf('.')+1).concat(name);
try {
- implementation = (Geometries) Class.forName(classname).newInstance();
+ implementation = (Geometries) Class.forName(classname).getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException | LinkageError e) {
LogRecord record = Resources.forLocale(null).getLogRecord(Level.CONFIG,
Resources.Keys.OptionalLibraryNotFound_2, name, e.toString());
@@ -163,8 +161,6 @@ public abstract class Geometries<G> {
* or {@code null} if the given object is not a recognized implementation.
*
* @see #createPoint(double, double)
- *
- * @see #getCoordinateReferenceSystem(Object)
*/
public static double[] getCoordinate(final Object point) {
for (Geometries<?> g = implementation; g != null; g = g.fallback) {
@@ -227,6 +223,15 @@ public abstract class Geometries<G> {
}
/**
+ * Parses the given WKT.
+ *
+ * @param wkt the WKT to parse.
+ * @return the geometry object for the given WKT.
+ * @throws Exception if the WKT can not be parsed. The exception sub-class depends on the implementation.
+ */
+ public abstract Object parseWKT(String wkt) throws Exception;
+
+ /**
* Creates a two-dimensional point from the given coordinate. If the CRS is geographic, then the
* (x,y) values should be (longitude, latitude) for compliance with usage in ESRI and JTS libraries.
*
@@ -288,43 +293,6 @@ public abstract class Geometries<G> {
}
/**
- * Parses the given WKT.
- *
- * @param wkt the WKT to parse.
- * @return the geometry object for the given WKT.
- * @throws Exception if the WKT can not be parsed. The exception sub-class depends on the implementation.
- */
- public abstract Object parseWKT(String wkt) throws Exception;
-
- /**
- * If the given geometry is an implementation of this library, returns its coordinate reference system.
- * Otherwise returns {@code null}.
- *
- * @param geometry the geometry from which to get the CRS.
- * @return the coordinate reference system, or {@code null} if none.
- * @throws FactoryException if the CRS can not be created from the SRID code.
- */
- CoordinateReferenceSystem tryGetCoordinateReferenceSystem(Object geometry) throws FactoryException {
- return null;
- }
-
- /**
- * If the given object is one of the recognized geometry implementations, gets its Coordinate Reference System (CRS).
- * Otherwise returns {@code null}.
- *
- * @param geometry the geometry from which to get the CRS.
- * @return the coordinate reference system, or {@code null} if none.
- * @throws FactoryException if the CRS can not be created from the SRID code.
- */
- public static CoordinateReferenceSystem getCoordinateReferenceSystem(final Object geometry) throws FactoryException {
- for (Geometries<?> g = implementation; g != null; g = g.fallback) {
- CoordinateReferenceSystem crs = g.tryGetCoordinateReferenceSystem(geometry);
- if (crs != null) return crs;
- }
- return null;
- }
-
- /**
* Returns an error message for an unsupported geometry object.
*
* @param dimension number of dimensions (2 or 3) requested for the geometry object.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
index 27879af..9234435 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
@@ -20,12 +20,6 @@ import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.Map;
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.CoordinateOperation;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.TransformException;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
@@ -37,12 +31,9 @@ import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.ParseException;
import org.apache.sis.geometry.GeneralEnvelope;
-import org.apache.sis.internal.feature.jts.GeometryCoordinateTransform;
import org.apache.sis.setup.GeometryLibrary;
import org.apache.sis.math.Vector;
-import org.apache.sis.referencing.CRS;
import org.apache.sis.util.Classes;
-import org.apache.sis.util.Utilities;
/**
@@ -56,13 +47,7 @@ import org.apache.sis.util.Utilities;
* @since 0.7
* @module
*/
-public final class JTS extends Geometries<Geometry> {
- /**
- * Key used in {@linkplain Geometry#getUserData() user data} map for storing
- * an instance of {@link CoordinateReferenceSystem}.
- */
- public static final String CRS_KEY = "CRS";
-
+final class JTS extends Geometries<Geometry> {
/**
* The factory to use for creating JTS geometries. Currently set to a factory using
* double-precision floating point numbers and a spatial-reference ID of 0.
@@ -78,6 +63,17 @@ public final class JTS extends Geometries<Geometry> {
}
/**
+ * Parses the given WKT.
+ *
+ * @return the geometry object for the given WKT.
+ * @throws ParseException if the WKT can not be parsed.
+ */
+ @Override
+ public Object parseWKT(final String wkt) throws ParseException {
+ return new WKTReader(factory).read(wkt);
+ }
+
+ /**
* If the given object is a JTS geometry, returns a short string representation of the class name.
*/
@Override
@@ -260,134 +256,4 @@ public final class JTS extends Geometries<Geometry> {
toLineString(coordinates, lines);
return toGeometry(lines);
}
-
- /**
- * Parses the given WKT.
- *
- * @return the geometry object for the given WKT.
- * @throws ParseException if the WKT can not be parsed.
- */
- @Override
- public Object parseWKT(final String wkt) throws ParseException {
- return new WKTReader(factory).read(wkt);
- }
-
- /**
- * Gets the Coordinate Reference System (CRS) from the given geometry.
- * This method expects the CRS to be stored in one the following ways:
- *
- * <ul>
- * <li>Geometry {@linkplain Geometry#getUserData() user data} is an instance of {@code CoordinateReferenceSystem}.</li>
- * <li>{@linkplain Geometry#getUserData() user data} is a (@link Map} with a value for the {@value #CRS_KEY} key.</li>
- * <li>Geometry SRID is strictly positive, in which case it is interpreted as an EPSG code.</li>
- * </ul>
- *
- * If none of the above is valid, {@code null} is returned.
- *
- * @param geometry the geometry from which to get the CRS.
- * @return the coordinate reference system, or {@code null} if none.
- * @throws FactoryException if the CRS can not be created from the SRID code.
- */
- @Override
- CoordinateReferenceSystem tryGetCoordinateReferenceSystem(final Object geometry) throws FactoryException {
- if (geometry instanceof Geometry) {
- final Geometry jts = (Geometry) geometry;
- final Object userData = jts.getUserData();
- if (userData instanceof CoordinateReferenceSystem) {
- return (CoordinateReferenceSystem) userData;
- } else if (userData instanceof Map<?,?>) {
- final Map<?,?> map = (Map<?,?>) userData;
- final Object value = map.get(CRS_KEY);
- if (value instanceof CoordinateReferenceSystem) {
- return (CoordinateReferenceSystem) value;
- }
- }
- /*
- * Fallback on SRID.
- */
- final int srid = jts.getSRID();
- if (srid > 0) {
- return CRS.forCode("EPSG:" + srid);
- }
- }
- return super.tryGetCoordinateReferenceSystem(geometry);
- }
-
- /**
- * Transform given geometry to a new CoordinateReferenceSystem.
- *
- * <p>
- * If CoordinateReferenceSystem of geometry is null, geometry is returned unchanged.
- * </p>
- * <p>
- * If geometry has no CoordinateReferenceSystem a TransformException is throwed.
- * </p>
- *
- * @param geometry source geometry
- * @param targetCrs target CoordinateReferenceSystem
- * @return transformed geometry, or same geometry if it is already in target crs
- * @throws org.opengis.referencing.operation.TransformException if geometry
- * has no CRS or failed to apply transform.
- * @throws org.opengis.util.FactoryException
- */
- public static Geometry transform(Geometry geometry, CoordinateReferenceSystem targetCrs)
- throws TransformException, FactoryException
- {
- if (geometry == null || targetCrs == null) {
- return geometry;
- }
- final CoordinateReferenceSystem sourceCrs = getCoordinateReferenceSystem(geometry);
- if (sourceCrs == null) {
- throw new TransformException("Geometry CRS is undefined");
- } else if (Utilities.equalsIgnoreMetadata(sourceCrs, targetCrs)) {
- return geometry;
- }
- return transform(geometry, CRS.findOperation(sourceCrs, targetCrs, null));
- }
-
- /**
- * Transform geometry, result is a new geometry.
- *
- * <p>
- * If geometry or operation is null, geometry is returned unchanged.
- * </p>
- *
- * TODO : handle antemeridian cases.
- *
- * @param geometry
- * @param operation
- * @return
- * @throws TransformException if transformation failed
- */
- public static Geometry transform(Geometry geometry, CoordinateOperation operation) throws TransformException {
- if (geometry == null || operation == null) {
- return geometry;
- }
- geometry = transform(geometry, operation.getMathTransform());
- geometry.setUserData(operation.getTargetCRS());
- return geometry;
- }
-
- /**
- * Transform geometry, result is a new geometry.
- *
- * <p>
- * If geometry or transform is null, geometry is returned unchanged.
- * </p>
- *
- * @param geometry
- * @param transform
- * @return transformed geometry or null.
- * @throws TransformException if transformation failed
- */
- public static Geometry transform(Geometry geometry, MathTransform transform) throws TransformException {
- if (geometry == null || transform == null) {
- return geometry;
- }
- final GeometryCoordinateTransform gct = new GeometryCoordinateTransform(transform, geometry.getFactory());
- final Geometry result = gct.transform(geometry);
- result.setSRID(geometry.getSRID());
- result.setUserData(geometry.getUserData());
- return result;
- }
}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryCoordinateTransform.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryCoordinateTransform.java
index fa9307d..43269e0 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryCoordinateTransform.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryCoordinateTransform.java
@@ -22,17 +22,20 @@ import org.locationtech.jts.geom.GeometryFactory;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
+
/**
- * This implementation use a MathTransform to transform each coordinate of
- * the geometry.
+ * A geometry transformer which uses a {@link MathTransform} for changing coordinate values.
+ * This class does not change the number of points.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
public class GeometryCoordinateTransform extends GeometryTransform {
-
+ /**
+ * The transform to apply on coordinate values.
+ */
private final MathTransform transform;
public GeometryCoordinateTransform(MathTransform transform) {
@@ -53,7 +56,7 @@ public class GeometryCoordinateTransform extends GeometryTransform {
protected CoordinateSequence transform(CoordinateSequence in, int minpoints) throws TransformException {
final int dim = in.getDimension();
final int size = in.size();
- final CoordinateSequence out = csf.create(size, dim);
+ final CoordinateSequence out = coordinateFactory.create(size, dim);
final double[] val = new double[dim];
for (int i = 0; i<size; i++) {
@@ -78,5 +81,4 @@ public class GeometryCoordinateTransform extends GeometryTransform {
}
return out;
}
-
}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryTransform.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryTransform.java
index 9c0be5c..4fca59d 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryTransform.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/GeometryTransform.java
@@ -30,43 +30,49 @@ import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.opengis.referencing.operation.TransformException;
+
/**
- * Abstract class parent to all JTS geometry transformations.
- * This class decompose the geometry to it's most primitive element, the
- * CoordinateSequence, then rebuild the geometry.
+ * An operation transforming a geometry into another geometry. This class decomposes the geometry into it's
+ * most primitive elements, the {@link CoordinateSequence}, applies an operation, then rebuilds the geometry.
+ * The operation may change coordinate values (for example a map projection), but not necessarily. An operation
+ * could also be a clipping for example.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
public abstract class GeometryTransform {
+ /**
+ * The factory to use for creating geometries.
+ */
+ private final GeometryFactory geometryFactory;
- protected final GeometryFactory gf;
- protected final CoordinateSequenceFactory csf;
+ /**
+ * The factory to use for creating sequences of coordinate tuples.
+ */
+ protected final CoordinateSequenceFactory coordinateFactory;
- public GeometryTransform() {
- this((CoordinateSequenceFactory) null);
+ protected GeometryTransform() {
+ this((GeometryFactory) null);
}
- public GeometryTransform(final CoordinateSequenceFactory csf) {
- if (csf == null) {
- this.gf = new GeometryFactory();
- this.csf = gf.getCoordinateSequenceFactory();
+ protected GeometryTransform(final CoordinateSequenceFactory factory) {
+ if (factory == null) {
+ geometryFactory = new GeometryFactory();
+ coordinateFactory = geometryFactory.getCoordinateSequenceFactory();
} else {
- this.csf = csf;
- this.gf = new GeometryFactory(csf);
+ coordinateFactory = factory;
+ geometryFactory = new GeometryFactory(factory);
}
}
- public GeometryTransform(final GeometryFactory gf) {
- if (gf == null) {
- this.gf = new GeometryFactory();
- this.csf = gf.getCoordinateSequenceFactory();
- } else {
- this.csf = gf.getCoordinateSequenceFactory();
- this.gf = gf;
+ protected GeometryTransform(GeometryFactory factory) {
+ if (factory == null) {
+ factory = new GeometryFactory();
}
+ geometryFactory = factory;
+ coordinateFactory = factory.getCoordinateSequenceFactory();
}
public Geometry transform(final Geometry geom) throws TransformException {
@@ -87,33 +93,32 @@ public abstract class GeometryTransform {
} else if (geom instanceof GeometryCollection) {
return transform((GeometryCollection) geom);
} else {
- throw new IllegalArgumentException("Geometry type is unknowed or null : " + geom);
+ throw new IllegalArgumentException("Geometry type is unknown or null: " + geom);
}
}
protected Point transform(final Point geom) throws TransformException {
final CoordinateSequence coord = geom.getCoordinateSequence();
- return gf.createPoint(transform(coord, 1));
+ return geometryFactory.createPoint(transform(coord, 1));
}
protected MultiPoint transform(final MultiPoint geom) throws TransformException {
final int nbGeom = geom.getNumGeometries();
-
final Point[] subs = new Point[geom.getNumGeometries()];
for (int i = 0; i < nbGeom; i++) {
subs[i] = transform((Point) geom.getGeometryN(i));
}
- return gf.createMultiPoint(subs);
+ return geometryFactory.createMultiPoint(subs);
}
protected LineString transform(final LineString geom) throws TransformException {
final CoordinateSequence seq = transform(geom.getCoordinateSequence(), 2);
- return gf.createLineString(seq);
+ return geometryFactory.createLineString(seq);
}
protected LinearRing transform(final LinearRing geom) throws TransformException {
final CoordinateSequence seq = transform(geom.getCoordinateSequence(), 4);
- return gf.createLinearRing(seq);
+ return geometryFactory.createLinearRing(seq);
}
protected MultiLineString transform(final MultiLineString geom) throws TransformException {
@@ -121,7 +126,7 @@ public abstract class GeometryTransform {
for (int i = 0; i < subs.length; i++) {
subs[i] = transform((LineString) geom.getGeometryN(i));
}
- return gf.createMultiLineString(subs);
+ return geometryFactory.createMultiLineString(subs);
}
protected Polygon transform(final Polygon geom) throws TransformException {
@@ -130,7 +135,7 @@ public abstract class GeometryTransform {
for (int i = 0; i < holes.length; i++) {
holes[i] = transform((LinearRing) geom.getInteriorRingN(i));
}
- return gf.createPolygon(exterior, holes);
+ return geometryFactory.createPolygon(exterior, holes);
}
protected MultiPolygon transform(final MultiPolygon geom) throws TransformException {
@@ -138,7 +143,7 @@ public abstract class GeometryTransform {
for (int i = 0; i < subs.length; i++) {
subs[i] = transform((Polygon) geom.getGeometryN(i));
}
- return gf.createMultiPolygon(subs);
+ return geometryFactory.createMultiPolygon(subs);
}
protected GeometryCollection transform(final GeometryCollection geom) throws TransformException {
@@ -146,16 +151,16 @@ public abstract class GeometryTransform {
for (int i = 0; i < subs.length; i++) {
subs[i] = transform(geom.getGeometryN(i));
}
- return gf.createGeometryCollection(subs);
+ return geometryFactory.createGeometryCollection(subs);
}
/**
+ * Transforms the given sequence of coordinate tuples, producing a new sequence of tuples.
*
- * @param sequence Sequence to transform
- * @param minpoints Minimum number of point to preserve
- * @return transformed sequence
- * @throws TransformException
+ * @param sequence sequence of coordinate tuples to transform.
+ * @param minpoints minimum number of points to preserve.
+ * @return the transformed sequence of coordinate tuples.
+ * @throws TransformException if an error occurred while transforming a tuple.
*/
protected abstract CoordinateSequence transform(CoordinateSequence sequence, int minpoints) throws TransformException;
-
}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
new file mode 100644
index 0000000..019c7d1
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
@@ -0,0 +1,156 @@
+/*
+ * 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.feature.jts;
+
+import java.util.Map;
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.util.Static;
+import org.apache.sis.util.Utilities;
+import org.locationtech.jts.geom.Geometry;
+
+
+/**
+ * Utilities for Java Topology Suite (JTS) objects.
+ * We use this class for functionalities not supported by Apache SIS with other libraries.
+ * For library-agnostic functionalities, see {@link org.apache.sis.internal.feature.Geometries} instead.
+ *
+ * @author Johann Sorel (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+public final class JTS extends Static {
+ /**
+ * Key used in {@linkplain Geometry#getUserData() user data} map for storing an instance of {@link CoordinateReferenceSystem}.
+ *
+ * @see #getCoordinateReferenceSystem(Geometry)
+ */
+ public static final String CRS_KEY = "CRS";
+
+ /**
+ * Do not allow instantiation of this class.
+ */
+ private JTS() {
+ }
+
+ /**
+ * Gets the Coordinate Reference System (CRS) from the given geometry.
+ * This method expects the CRS to be stored in one the following ways:
+ *
+ * <ul>
+ * <li>Geometry {@linkplain Geometry#getUserData() user data} is an instance of {@code CoordinateReferenceSystem}.</li>
+ * <li>{@linkplain Geometry#getUserData() user data} is a (@link Map} with a value for the {@value #CRS_KEY} key.</li>
+ * <li>Geometry SRID is strictly positive, in which case it is interpreted as an EPSG code.</li>
+ * </ul>
+ *
+ * If none of the above is valid, {@code null} is returned.
+ *
+ * @param geometry the geometry from which to get the CRS, or {@code null}.
+ * @return the coordinate reference system, or {@code null} if none.
+ * @throws FactoryException if the CRS can not be created from the SRID code.
+ */
+ public static CoordinateReferenceSystem getCoordinateReferenceSystem(final Geometry geometry) throws FactoryException {
+ if (geometry != null) {
+ final Object userData = geometry.getUserData();
+ if (userData instanceof CoordinateReferenceSystem) {
+ return (CoordinateReferenceSystem) userData;
+ } else if (userData instanceof Map<?,?>) {
+ final Map<?,?> map = (Map<?,?>) userData;
+ final Object value = map.get(CRS_KEY);
+ if (value instanceof CoordinateReferenceSystem) {
+ return (CoordinateReferenceSystem) value;
+ }
+ }
+ /*
+ * Fallback on SRID with the assumption that they are EPSG codes.
+ */
+ final int srid = geometry.getSRID();
+ if (srid > 0) {
+ return CRS.forCode(Constants.EPSG + ':' + srid);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Transform the given geometry to the specified Coordinate Reference System (CRS).
+ * If the given CRS or the given geometry is null, the geometry is returned unchanged.
+ * If the geometry has no Coordinate Reference System, a {@link TransformException} is thrown.
+ *
+ * @param geometry the geometry to transform, or {@code null}.
+ * @param targetCRS the target coordinate reference system, or {@code null}.
+ * @return the transformed geometry, or the same geometry if it is already in target CRS.
+ * @throws TransformException if the given geometry has no CRS or can not be transformed.
+ * @throws FactoryException if transformation to the target CRS can not be constructed.
+ */
+ public static Geometry transform(Geometry geometry, final CoordinateReferenceSystem targetCRS)
+ throws TransformException, FactoryException
+ {
+ if (geometry != null && targetCRS != null) {
+ final CoordinateReferenceSystem sourceCRS = getCoordinateReferenceSystem(geometry);
+ if (sourceCRS == null) {
+ throw new TransformException("Geometry CRS is undefined.");
+ }
+ if (!Utilities.equalsIgnoreMetadata(sourceCRS, targetCRS)) {
+ geometry = transform(geometry, CRS.findOperation(sourceCRS, targetCRS, null));
+ }
+ }
+ return geometry;
+ }
+
+ /**
+ * Transform the given geometry using the given coordinate operation.
+ * If the geometry or the operation is null, then the geometry is returned unchanged.
+ *
+ * @todo Handle antimeridian case.
+ *
+ * @param geometry the geometry to transform, or {@code null}.
+ * @param operation the coordinate operation to apply, or {@code null}.
+ * @return the transformed geometry, or the same geometry if it is already in target CRS.
+ * @throws TransformException if the given geometry can not be transformed.
+ */
+ public static Geometry transform(Geometry geometry, final CoordinateOperation operation) throws TransformException {
+ if (geometry != null && operation != null) {
+ geometry = transform(geometry, operation.getMathTransform());
+ geometry.setUserData(operation.getTargetCRS());
+ }
+ return geometry;
+ }
+
+ /**
+ * Transform the given geometry using the given math transform.
+ * If the geometry or the transform is null or identity, then the geometry is returned unchanged.
+ *
+ * @param geometry the geometry to transform, or {@code null}.
+ * @param transform the transform to apply, or {@code null}.
+ * @return the transformed geometry, or the same geometry if it is already in target CRS.
+ * @throws TransformException if the given geometry can not be transformed.
+ */
+ public static Geometry transform(Geometry geometry, MathTransform transform) throws TransformException {
+ if (geometry != null && transform != null) {
+ final GeometryCoordinateTransform gct = new GeometryCoordinateTransform(transform, geometry.getFactory());
+ geometry = gct.transform(geometry);
+ }
+ return geometry;
+ }
+}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/package-info.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/package-info.java
new file mode 100644
index 0000000..190a783
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * Methods specific to the Java Topology Suite (JTS).
+ *
+ * <STRONG>Do not use!</STRONG>
+ *
+ * This package is for internal use by SIS only. Classes in this package
+ * may change in incompatible ways in any future version without notice.
+ *
+ * @author Johann Sorel (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+package org.apache.sis.internal.feature.jts;
diff --git a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java
index a6bb921..4105b5a 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java
@@ -39,7 +39,7 @@ public abstract strictfp class GeometriesTestCase extends TestCase {
/**
* The factory to test.
*/
- final Geometries<?> factory;
+ private final Geometries<?> factory;
/**
* The geometry created by the test. Provided for allowing sub-classes to perform additional verifications.
diff --git a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/JTSTest.java b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/JTSTest.java
index 4fedb0f..8347c6b 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/JTSTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/JTSTest.java
@@ -16,17 +16,8 @@
*/
package org.apache.sis.internal.feature;
-import java.util.Collections;
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.operation.TransformException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiLineString;
-import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -94,66 +85,4 @@ public final strictfp class JTSTest extends GeometriesTestCase {
new Coordinate(15, 11),
new Coordinate(13, 10)}, mp.getGeometryN(2).getCoordinates());
}
-
- /**
- * Tests {@link JTS#tryGetCoordinateReferenceSystem(Object)}.
- *
- * @throws FactoryException if an EPSG code can not be resolved.
- */
- @Test
- public void testGetCoordinateReferenceSystem() throws FactoryException {
- final GeometryFactory gf = new GeometryFactory();
- final Geometry geometry = gf.createPoint(new Coordinate(5, 6));
-
- CoordinateReferenceSystem crs = factory.tryGetCoordinateReferenceSystem(geometry);
- assertNull(crs);
-
- // Test CRS as user data.
- geometry.setUserData(CommonCRS.ED50.geographic());
- assertEquals(CommonCRS.ED50.geographic(), factory.tryGetCoordinateReferenceSystem(geometry));
-
- // Test CRS as map value.
- geometry.setUserData(Collections.singletonMap(JTS.CRS_KEY, CommonCRS.NAD83.geographic()));
- assertEquals(CommonCRS.NAD83.geographic(), factory.tryGetCoordinateReferenceSystem(geometry));
-
- // Test CRS as srid.
- geometry.setUserData(null);
- geometry.setSRID(4326);
- assertEquals(CommonCRS.WGS84.geographic(), factory.tryGetCoordinateReferenceSystem(geometry));
- }
-
- /**
- * Tests {@link JTS#transform(org.locationtech.jts.geom.Geometry, org.opengis.referencing.crs.CoordinateReferenceSystem) }.
- * Tests {@link JTS#transform(org.locationtech.jts.geom.Geometry, org.opengis.referencing.operation.CoordinateOperation) }.
- * Tests {@link JTS#transform(org.locationtech.jts.geom.Geometry, org.opengis.referencing.operation.MathTransform) }.
- */
- @Test
- public void testTransform() throws FactoryException, TransformException {
- final GeometryFactory gf = new GeometryFactory();
- final Geometry in = gf.createPoint(new Coordinate(5, 6));
-
- // test exception when transforming geometry without CRS.
- try {
- JTS.transform(in, CommonCRS.WGS84.geographic());
- fail("Geometry has no CRS, transform should have failed");
- } catch (TransformException ex) {
- //ok
- }
-
- // test axes inversion transform
- in.setUserData(CommonCRS.WGS84.normalizedGeographic());
- Geometry out = JTS.transform(in, CommonCRS.WGS84.geographic());
- assertTrue(out instanceof Point);
- assertEquals(6.0, ((Point) out).getX(), 0.0);
- assertEquals(5.0, ((Point) out).getY(), 0.0);
- assertEquals(CommonCRS.WGS84.geographic(), out.getUserData());
-
- // test affine transform, user data must be preserved
- final AffineTransform2D trs = new AffineTransform2D(1,0,0,1,10,20);
- out = JTS.transform(in, trs);
- assertTrue(out instanceof Point);
- assertEquals(15.0, ((Point) out).getX(), 0.0);
- assertEquals(26.0, ((Point) out).getY(), 0.0);
- assertEquals(CommonCRS.WGS84.normalizedGeographic(), out.getUserData());
- }
}
diff --git a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/JTSTest.java b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/jts/JTSTest.java
similarity index 59%
copy from core/sis-feature/src/test/java/org/apache/sis/internal/feature/JTSTest.java
copy to core/sis-feature/src/test/java/org/apache/sis/internal/feature/jts/JTSTest.java
index 4fedb0f..4959846 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/JTSTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/jts/JTSTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.feature;
+package org.apache.sis.internal.feature.jts;
import java.util.Collections;
import org.opengis.util.FactoryException;
@@ -24,9 +24,9 @@ import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.MultiLineString;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
+import org.apache.sis.test.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -35,68 +35,14 @@ import static org.junit.Assert.*;
/**
* Tests {@link JTS} implementation.
*
- * @author Martin Desruisseaux (Geomatys)
* @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
-public final strictfp class JTSTest extends GeometriesTestCase {
+public final strictfp class JTSTest extends TestCase {
/**
- * Creates a new test case.
- */
- public JTSTest() {
- super(new JTS());
- }
-
- /**
- * Tests {@link JTS#createPolyline(int, Vector...)}.
- */
- @Test
- @Override
- public void testCreatePolyline() {
- super.testCreatePolyline();
- final MultiLineString mp = (MultiLineString) geometry;
- assertEquals("numGeometries", 2, mp.getNumGeometries());
- verifyTwoFirstGeometries(mp);
- }
-
- /**
- * Verifies the coordinates of the two first geometries of the given multi line string.
- * If there is more than 2 geometries, it is caller responsibility to verify the other ones.
- */
- private static void verifyTwoFirstGeometries(final MultiLineString mp) {
- assertArrayEquals(new Coordinate[] {
- new Coordinate(4, 5),
- new Coordinate(7, 9),
- new Coordinate(9, 3),
- new Coordinate(4, 5)}, mp.getGeometryN(0).getCoordinates());
-
- assertArrayEquals(new Coordinate[] {
- new Coordinate(-3, -2),
- new Coordinate(-2, -5),
- new Coordinate(-1, -6)}, mp.getGeometryN(1).getCoordinates());
- }
-
- /**
- * Tests {@link Geometries#tryMergePolylines(Object, Iterator)}.
- */
- @Test
- @Override
- public void testTryMergePolylines() {
- super.testTryMergePolylines();
- final MultiLineString mp = (MultiLineString) geometry;
- assertEquals("numGeometries", 3, mp.getNumGeometries());
- verifyTwoFirstGeometries(mp);
- assertArrayEquals(new Coordinate[] {
- new Coordinate(13, 11),
- new Coordinate(14, 12),
- new Coordinate(15, 11),
- new Coordinate(13, 10)}, mp.getGeometryN(2).getCoordinates());
- }
-
- /**
- * Tests {@link JTS#tryGetCoordinateReferenceSystem(Object)}.
+ * Tests {@link JTS#getCoordinateReferenceSystem(Geometry)}.
*
* @throws FactoryException if an EPSG code can not be resolved.
*/
@@ -105,21 +51,21 @@ public final strictfp class JTSTest extends GeometriesTestCase {
final GeometryFactory gf = new GeometryFactory();
final Geometry geometry = gf.createPoint(new Coordinate(5, 6));
- CoordinateReferenceSystem crs = factory.tryGetCoordinateReferenceSystem(geometry);
+ CoordinateReferenceSystem crs = JTS.getCoordinateReferenceSystem(geometry);
assertNull(crs);
// Test CRS as user data.
geometry.setUserData(CommonCRS.ED50.geographic());
- assertEquals(CommonCRS.ED50.geographic(), factory.tryGetCoordinateReferenceSystem(geometry));
+ assertEquals(CommonCRS.ED50.geographic(), JTS.getCoordinateReferenceSystem(geometry));
// Test CRS as map value.
geometry.setUserData(Collections.singletonMap(JTS.CRS_KEY, CommonCRS.NAD83.geographic()));
- assertEquals(CommonCRS.NAD83.geographic(), factory.tryGetCoordinateReferenceSystem(geometry));
+ assertEquals(CommonCRS.NAD83.geographic(), JTS.getCoordinateReferenceSystem(geometry));
// Test CRS as srid.
geometry.setUserData(null);
geometry.setSRID(4326);
- assertEquals(CommonCRS.WGS84.geographic(), factory.tryGetCoordinateReferenceSystem(geometry));
+ assertEquals(CommonCRS.WGS84.geographic(), JTS.getCoordinateReferenceSystem(geometry));
}
/**
@@ -154,6 +100,5 @@ public final strictfp class JTSTest extends GeometriesTestCase {
assertTrue(out instanceof Point);
assertEquals(15.0, ((Point) out).getX(), 0.0);
assertEquals(26.0, ((Point) out).getY(), 0.0);
- assertEquals(CommonCRS.WGS84.normalizedGeographic(), out.getUserData());
}
}
diff --git a/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java b/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
index 3c18e56..f2aa5c8 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
@@ -55,6 +55,7 @@ import org.junit.BeforeClass;
org.apache.sis.internal.feature.Java2DTest.class,
org.apache.sis.internal.feature.ESRITest.class,
org.apache.sis.internal.feature.JTSTest.class,
+ org.apache.sis.internal.feature.jts.JTSTest.class,
org.apache.sis.feature.builder.CharacteristicTypeBuilderTest.class,
org.apache.sis.feature.builder.AttributeTypeBuilderTest.class,
org.apache.sis.feature.builder.AssociationRoleBuilderTest.class,