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
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new 6aa28f8 Modify the JTS factory class for building JTS Polygon more
directly, and complete javadoc.
6aa28f8 is described below
commit 6aa28f899b162add0d7e6bd5a603d1dd8ccbf355
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Jan 18 18:04:11 2020 +0100
Modify the JTS factory class for building JTS Polygon more directly, and
complete javadoc.
---
.../java/org/apache/sis/internal/feature/ESRI.java | 20 +--
.../apache/sis/internal/feature/Geometries.java | 7 +-
.../java/org/apache/sis/internal/feature/JTS.java | 144 +++++++++++++--------
.../org/apache/sis/internal/feature/Java2D.java | 32 +++--
.../sis/internal/feature/j2d/package-info.java | 2 +-
.../org/apache/sis/internal/feature/jts/JTS.java | 62 +++++----
6 files changed, 161 insertions(+), 106 deletions(-)
diff --git
a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
index db06990..87a3a05 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
@@ -18,29 +18,28 @@ package org.apache.sis.internal.feature;
import java.nio.ByteBuffer;
import java.util.Iterator;
-
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.Envelope2D;
import com.esri.core.geometry.MultiPath;
+import com.esri.core.geometry.MultiVertexGeometry;
import com.esri.core.geometry.Polyline;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Point2D;
import com.esri.core.geometry.Point3D;
+import com.esri.core.geometry.WkbImportFlags;
import com.esri.core.geometry.WktImportFlags;
import com.esri.core.geometry.WktExportFlags;
+import com.esri.core.geometry.OperatorImportFromWkb;
import com.esri.core.geometry.OperatorImportFromWkt;
import com.esri.core.geometry.OperatorExportToWkt;
import com.esri.core.geometry.OperatorCentroid2D;
-
import org.apache.sis.geometry.GeneralEnvelope;
-import org.apache.sis.math.Vector;
import org.apache.sis.setup.GeometryLibrary;
+import org.apache.sis.math.Vector;
import org.apache.sis.util.Classes;
import org.apache.sis.util.Debug;
-import com.esri.core.geometry.*;
-
/**
* Centralizes some usages of ESRI geometry API by Apache SIS.
@@ -48,6 +47,7 @@ import com.esri.core.geometry.*;
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
+ * @author Alexis Manin (Geomatys)
* @version 1.1
* @since 0.7
* @module
@@ -257,17 +257,19 @@ add: for (;;) {
}
/**
- * Parses the given WKT.
+ * Parses the given Well Known Text (WKT).
*/
@Override
public Geometry parseWKT(final String wkt) {
return
OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults,
Geometry.Type.Unknown, wkt, null);
}
+ /**
+ * Reads the given Well Known Binary (WKB).
+ */
@Override
- public Geometry parseWKB(byte[] source) {
- final OperatorImportFromWkb op = OperatorImportFromWkb.local();
- return op.execute(WkbImportFlags.wkbImportDefaults,
Geometry.Type.Unknown, ByteBuffer.wrap(source), null);
+ public Geometry parseWKB(final ByteBuffer data) {
+ return
OperatorImportFromWkb.local().execute(WkbImportFlags.wkbImportDefaults,
Geometry.Type.Unknown, data, null);
}
/**
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 d040593..a36c871 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
@@ -16,6 +16,7 @@
*/
package org.apache.sis.internal.feature;
+import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.LogRecord;
@@ -242,6 +243,9 @@ public abstract class Geometries<G> {
* and returns {@code true}. Otherwise returns {@code false}. The default
implementation returns
* {@code false} because only a few geometry implementations can store CRS
information.
*
+ * <p>This method should be invoked only for newly created geometries. If
the geometry library supports
+ * user objects (e.g. JTS), there is no guarantees that this method will
not overwrite user setting.</p>
+ *
* @see #tryTransform(Object, CoordinateOperation,
CoordinateReferenceSystem)
*/
boolean trySetCoordinateReferenceSystem(Object geometry,
CoordinateReferenceSystem crs) {
@@ -422,12 +426,13 @@ public abstract class Geometries<G> {
/**
* Reads the given bytes as a Well Known Binary (WKB) encoded geometry.
+ * Whether this method changes the buffer position or not is
implementation-dependent.
*
* @param data the binary data in WKB format. Can not be null.
* @return decoded geometry (never {@code null}).
* @throws Exception if the WKB can not be parsed. The exception sub-class
depends on the implementation.
*/
- public abstract G parseWKB(byte[] data) throws Exception;
+ public abstract G parseWKB(ByteBuffer data) throws Exception;
/**
* Creates a two-dimensional point from the given coordinate. If the CRS
is geographic, then the
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 d296c5b..2ea8abc 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
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Iterator;
+import java.nio.ByteBuffer;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.operation.CoordinateOperation;
@@ -30,6 +31,8 @@ import org.opengis.util.FactoryException;
import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.math.Vector;
import org.apache.sis.setup.GeometryLibrary;
+import org.apache.sis.internal.util.Strings;
+import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.Classes;
import org.apache.sis.util.Debug;
@@ -55,6 +58,7 @@ import org.locationtech.jts.io.WKTReader;
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
+ * @author Alexis Manin (Geomatys)
* @version 1.1
* @since 0.7
* @module
@@ -75,7 +79,7 @@ final class JTS extends Geometries<Geometry> {
}
/**
- * Parses the given WKT.
+ * Parses the given Well Known Text (WKT).
*
* @return the geometry object for the given WKT.
* @throws ParseException if the WKT can not be parsed.
@@ -85,9 +89,30 @@ final class JTS extends Geometries<Geometry> {
return new WKTReader(factory).read(wkt);
}
+ /**
+ * Reads the given Well Known Binary (WKB).
+ * This implementation does not change the buffer position.
+ */
@Override
- public Geometry parseWKB(byte[] source) throws ParseException {
- return new WKBReader(factory).read(source);
+ public Geometry parseWKB(final ByteBuffer data) throws ParseException {
+ byte[] array;
+ if (data.hasArray()) {
+ /*
+ * Try to use the underlying array without copy if possible.
+ * Copy only if the position or length does not match.
+ */
+ array = data.array();
+ int lower = data.arrayOffset();
+ int upper = data.limit() + lower;
+ lower += data.position();
+ if (lower != 0 || upper != array.length) {
+ array = Arrays.copyOfRange(array, lower, upper);
+ }
+ } else {
+ array = new byte[data.remaining()];
+ data.get(array);
+ }
+ return new WKBReader(factory).read(array);
}
/**
@@ -177,9 +202,8 @@ final class JTS extends Geometries<Geometry> {
/**
* If the given geometry is an implementation of this library, returns its
coordinate reference system.
- * Otherwise returns {@code null}.
- *
- * @see #tryTransform(Object, CoordinateOperation,
CoordinateReferenceSystem)
+ * This method overwrites any previous user object. This is okay for the
context in which Apache SIS
+ * uses this method, which is only for newly created geometries.
*/
@Override
final CoordinateReferenceSystem tryGetCoordinateReferenceSystem(final
Object geometry) throws FactoryException {
@@ -190,6 +214,11 @@ final class JTS extends Geometries<Geometry> {
}
}
+ /**
+ * If the given geometry is an implementation of this library, sets its
coordinate reference system.
+ *
+ * @see #tryTransform(Object, CoordinateOperation,
CoordinateReferenceSystem)
+ */
@Override
final boolean trySetCoordinateReferenceSystem(final Object geometry, final
CoordinateReferenceSystem crs) {
if (geometry instanceof Geometry) {
@@ -259,7 +288,7 @@ final class JTS extends Geometries<Geometry> {
throw new UnsupportedOperationException(unsupported(dimension));
}
final List<Coordinate> coordinates = new ArrayList<>(32);
- final List<LineString> lines = new ArrayList<>();
+ final List<Geometry> lines = new ArrayList<>();
for (final Vector v : coords) {
if (v != null) {
final int size = v.size();
@@ -276,17 +305,14 @@ final class JTS extends Geometries<Geometry> {
coordinates.add(c);
} else {
if (is3D) i++;
- toLineString(coordinates, lines);
+ toLineString(coordinates, lines, polygon);
coordinates.clear();
}
}
}
}
- toLineString(coordinates, lines);
- if (polygon) {
- return toPolygon(toGeometry(lines)); // TODO: create polygon
directly instead.
- }
- return toGeometry(lines);
+ toLineString(coordinates, lines, polygon);
+ return toGeometry(lines, polygon);
}
/**
@@ -295,64 +321,80 @@ final class JTS extends Geometries<Geometry> {
*
* @param geometries the polygons or linear rings to put in a
multi-polygons.
* @throws ClassCastException if an element in the array is not a JTS
geometry.
+ * @throws IllegalArgumentException if an element is a non-closed linear
string.
*/
@Override
public MultiPolygon createMultiPolygon(final Object[] geometries) {
final Polygon[] polygons = new Polygon[geometries.length];
for (int i=0; i<geometries.length; i++) {
- polygons[i] = toPolygon((Geometry) unwrap(geometries[i]));
- }
- return factory.createMultiPolygon(polygons);
- }
-
- private Polygon toPolygon(Geometry polyline) throws
IllegalArgumentException {
- if (polyline instanceof Polygon) {
- return (Polygon) polyline;
- }
- Polygon result = null;
- if (polyline instanceof LinearRing) {
- result = factory.createPolygon((LinearRing) polyline);
- } else if (polyline instanceof LineString) {
- final LineString myLine = (LineString) polyline;
- if (myLine.getEndPoint().equals(myLine.getStartPoint())) {
- result = factory.createPolygon(myLine.getCoordinateSequence());
+ final Object polyline = unwrap(geometries[i]);
+ final Polygon polygon;
+ if (polyline instanceof Polygon) {
+ polygon = (Polygon) polyline;
+ } else if (polyline instanceof LinearRing) {
+ polygon = factory.createPolygon((LinearRing) polyline);
+ copyMetadata((Geometry) polyline, polygon);
+ } else if (polyline instanceof LineString) {
+ // Let JTS throws an exception with its own error message if
the ring is not valid.
+ polygon = factory.createPolygon(((LineString)
polyline).getCoordinateSequence());
+ copyMetadata((Geometry) polyline, polygon);
+ } else {
+ throw new
ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_3,
+ Strings.bracket("geometries", i), Polygon.class,
Classes.getClass(polyline)));
}
+ polygons[i] = polygon;
}
- if (result == null) {
- throw new IllegalArgumentException("Input is not a closed line.");
- }
- copyMetadata(polyline, result);
- return result;
+ return factory.createMultiPolygon(polygons);
}
/**
* Makes a line string or linear ring from the given coordinates, and adds
the line string to the given list.
+ * If the {@code polygon} argument is {@code true}, then this method
creates polygons instead of line strings.
* If the given coordinates array is empty, then this method does nothing.
* This method does not modify the given coordinates list.
*/
- private void toLineString(final List<Coordinate> coordinates, final
List<LineString> addTo) {
+ private void toLineString(final List<Coordinate> coordinates, final
List<Geometry> addTo, final boolean polygon) {
final int s = coordinates.size();
if (s >= 2) {
- final LineString line;
final Coordinate[] ca = coordinates.toArray(new Coordinate[s]);
- if (ca[0].equals2D(ca[s-1])) {
- line = factory.createLinearRing(ca); // Throws an
exception if s < 4.
+ final Geometry geom;
+ if (polygon) {
+ geom = factory.createPolygon(ca);
+ } else if (ca[0].equals2D(ca[s-1])) {
+ geom = factory.createLinearRing(ca); // Throws an
exception if s < 4.
} else {
- line = factory.createLineString(ca); // Throws an
exception if contains duplicated point.
+ geom = factory.createLineString(ca); // Throws an
exception if contains duplicated point.
}
- addTo.add(line);
+ addTo.add(geom);
}
}
/**
- * Returns the given list of line string as a single geometry.
+ * Returns the given list of polygons or line strings as a single geometry.
+ *
+ * @param lines the polygons or lines strings.
+ * @return {@code true} if the given list contains {@link Polygon}
instances, or
+ * {@code false} if it contains {@link LineString} instances.
+ * @throws ArrayStoreException if the geometries in the given list are not
instances
+ * of the type specified by the {@code polygon} argument.
*/
- private Geometry toGeometry(final List<LineString> lines) {
+ @SuppressWarnings("SuspiciousToArrayCall") // Type controlled by
`polygon`.
+ private Geometry toGeometry(final List<Geometry> lines, final boolean
polygon) {
final int s = lines.size();
switch (s) {
- case 0: return factory.createLinearRing((Coordinate[]) null);
// Creates an empty linear ring.
- case 1: return lines.get(0);
- default: return factory.createMultiLineString(lines.toArray(new
LineString[s]));
+ case 0: {
+ // Create an empty polygon or linear ring.
+ return polygon ? factory.createPolygon ((Coordinate[]) null)
+ : factory.createLinearRing((Coordinate[]) null);
+ }
+ case 1: {
+ return lines.get(0);
+ }
+ default: {
+ // An ArrayStoreException here would be a bug in our use of
`polygon` boolean.
+ return polygon ? factory.createMultiPolygon
(lines.toArray(new Polygon [s]))
+ :
factory.createMultiLineString(lines.toArray(new LineString[s]));
+ }
}
}
@@ -367,14 +409,14 @@ final class JTS extends Geometries<Geometry> {
return null;
}
final List<Coordinate> coordinates = new ArrayList<>();
- final List<LineString> lines = new ArrayList<>();
+ final List<Geometry> lines = new ArrayList<>();
add: for (;;) {
if (next instanceof Point) {
final Coordinate pt = ((Point) next).getCoordinate();
if (!Double.isNaN(pt.x) && !Double.isNaN(pt.y)) {
coordinates.add(pt);
} else {
- toLineString(coordinates, lines);
+ toLineString(coordinates, lines, false);
coordinates.clear();
}
} else {
@@ -386,7 +428,7 @@ add: for (;;) {
lines.add(ls);
} else {
coordinates.addAll(Arrays.asList(ls.getCoordinates()));
- toLineString(coordinates, lines);
+ toLineString(coordinates, lines, false);
coordinates.clear();
}
}
@@ -398,8 +440,8 @@ add: for (;;) {
do if (!polylines.hasNext()) break add;
while ((next = polylines.next()) == null);
}
- toLineString(coordinates, lines);
- return toGeometry(lines);
+ toLineString(coordinates, lines, false);
+ return toGeometry(lines, false);
}
/**
@@ -429,7 +471,7 @@ add: for (;;) {
* @see #tryGetCoordinateReferenceSystem(Object)
*/
@Override
- final Geometry tryTransform(final Object geometry, final
CoordinateOperation operation, final CoordinateReferenceSystem targetCRS)
+ Geometry tryTransform(final Object geometry, final CoordinateOperation
operation, final CoordinateReferenceSystem targetCRS)
throws FactoryException, TransformException
{
if (geometry instanceof Geometry) {
diff --git
a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
index 6d6e1d6..5a67ad3 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.feature;
import java.util.List;
import java.util.Iterator;
+import java.nio.ByteBuffer;
import java.awt.Shape;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
@@ -42,6 +43,7 @@ import org.apache.sis.util.UnsupportedImplementationException;
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
+ * @author Alexis Manin (Geomatys)
* @version 1.1
* @since 0.7
* @module
@@ -127,6 +129,11 @@ final class Java2D extends Geometries<Shape> {
case 0: return ArraysExt.EMPTY_DOUBLE;
case 1: return coordinates.get(0);
default: {
+ /*
+ * Concatenate the coordinates of all polygons in a single
array. We lost the distinction
+ * between the different polygons, which is why this
method should not be used except for
+ * testing.
+ */
final double[] tgt = new
double[coordinates.stream().mapToInt((a) -> a.length).sum()];
int p = 0;
for (final double[] src : coordinates) {
@@ -168,7 +175,7 @@ final class Java2D extends Geometries<Shape> {
* @param length initial capacity.
* @return an initially empty path of the given type.
*/
- private Path2D createPath(final boolean isFloat, final int length) {
+ private static Path2D createPath(final boolean isFloat, final int length) {
return isFloat ? new Path2D.Float (Path2D.WIND_NON_ZERO, length)
: new Path2D.Double(Path2D.WIND_NON_ZERO, length);
}
@@ -202,6 +209,7 @@ final class Java2D extends Geometries<Shape> {
}
}
/*
+ * Shortcut (for performance reason) when building a single line
segment.
* Note: Point2D is not an instance of Shape, so we can not make a
special case for it.
*/
length /= BIDIMENSIONAL;
@@ -218,30 +226,27 @@ final class Java2D extends Geometries<Shape> {
return path;
}
}
+ /*
+ * General case if we could not use a shortcut.
+ */
final Path2D path = createPath(isFloat, length);
- double startX = Double.NaN, startY = Double.NaN;
- double lastX = Double.NaN, lastY = Double.NaN;
boolean lineTo = false;
for (final Vector v : coordinates) {
final int size = v.size();
for (int i=0; i<size;) {
final double x = v.doubleValue(i++);
final double y = v.doubleValue(i++);
- if (Double.isNaN(startX)) {
- startX = x;
- startY = y;
- }
if (Double.isNaN(x) || Double.isNaN(y)) {
- if (lastX == startX && lastY == startY) path.closePath();
+ if (polygon) {
+ path.closePath();
+ }
lineTo = false;
- startX = startY = Double.NaN;
} else if (lineTo) {
path.lineTo(x, y);
} else {
path.moveTo(x, y);
lineTo = true;
}
- lastX = x; lastY = y;
}
}
if (polygon) {
@@ -335,15 +340,18 @@ add: for (;;) {
}
/**
- * Parses the given WKT.
+ * Well Known Text (WKT) parsing not supported with Java2D.
*/
@Override
public Shape parseWKT(final String wkt) {
throw new UnsupportedImplementationException(unsupported("parseWKT"));
}
+ /**
+ * Well Known Binary (WKB) reading not supported with Java2D.
+ */
@Override
- public Shape parseWKB(byte[] source) {
+ public Shape parseWKB(ByteBuffer data) {
throw new UnsupportedImplementationException(unsupported("parseWKB"));
}
}
diff --git
a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/package-info.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/package-info.java
index 747ae56..ed904d7 100644
---
a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/package-info.java
+++
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/package-info.java
@@ -24,7 +24,7 @@
* may change in incompatible ways in any future version without notice.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.1
*
* @see org.apache.sis.internal.referencing.j2d
*
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
index 86813e1..9937e79 100644
---
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
@@ -17,29 +17,26 @@
package org.apache.sis.internal.feature.jts;
import java.util.Map;
-import java.util.Optional;
-
+import org.opengis.metadata.Identifier;
+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.opengis.util.FactoryException;
-
-import org.apache.sis.geometry.Envelope2D;
-import org.apache.sis.internal.system.Loggers;
-import org.apache.sis.internal.util.Constants;
-import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
import org.apache.sis.referencing.CRS;
import org.apache.sis.util.Static;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.resources.Errors;
-
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
+import org.apache.sis.geometry.Envelope2D;
+import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.referencing.IdentifiedObjects;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
-import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
-
/**
* Utilities for Java Topology Suite (JTS) objects.
@@ -50,7 +47,8 @@ import static
org.apache.sis.util.ArgumentChecks.ensureNonNull;
* For example we may replace it by a more general mechanism working also on
other geometry libraries.</p>
*
* @author Johann Sorel (Geomatys)
- * @version 1.0
+ * @author Alexis Manin (Geomatys)
+ * @version 1.1
* @since 1.0
* @module
*/
@@ -107,27 +105,27 @@ public final class JTS extends Static {
return null;
}
- public static Optional<CoordinateReferenceSystem>
setCoordinateReferenceSystem(final Geometry target, final
CoordinateReferenceSystem crs) {
- ensureNonNull("Target geometry", target);
- final Object ud = target.getUserData();
- if (ud == null) {
- // By security, we reset SRID in case old CRS was defined this way.
- target.setSRID(0);
- target.setUserData(crs);
- return Optional.empty();
- } else if (ud instanceof CoordinateReferenceSystem) {
- target.setUserData(crs);
- return Optional.of((CoordinateReferenceSystem) ud);
- } else if (ud instanceof Map) {
- final Map asMap = (Map) ud;
- // In case user-data contains other useful data, we don't switch
from map to CRS. We also reset SRID.
- final Object oldVal = asMap.put(CRS_KEY, crs);
- // By security, we reset SRID in case old CRS was defined this way.
- if (oldVal == null) {
- target.setSRID(0);
- }
+ /**
+ * Sets the Coordinate Reference System (CRS) in the specified geometry.
This method overwrite any previous
+ * user data; it should be invoked only when the geometry is known to not
store any other information.
+ * In current Apache SIS usage, this method is invoked only for newly
created geometries.
+ *
+ * <p>This method also sets the JTS SRID to EPSG code if such code can be
found. For performance reasons
+ * this method does not perform a full scan of EPSG database if the CRS
does not provide an EPSG code.</p>
+ *
+ * @param target the geometry where to store coordinate reference system
information.
+ * @param crs the CRS to store, or {@code null}.
+ */
+ public static void setCoordinateReferenceSystem(final Geometry target,
final CoordinateReferenceSystem crs) {
+ target.setUserData(crs);
+ int epsg = 0;
+ final Identifier id = IdentifiedObjects.getIdentifier(crs,
Citations.EPSG);
+ if (id != null) try {
+ epsg = Integer.parseInt(id.getCode());
+ } catch (NumberFormatException e) {
+ // Ignore. Note: this is also the exception if id.getCode() is
null.
}
- throw new IllegalArgumentException("Cannot modify input geometry,
because user-data does not comply with SIS convention (should be a map or null,
but was "+ud.getClass().getCanonicalName()+").");
+ target.setSRID(epsg);
}
/**