diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java b/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java index 7143d3971d..e4dc1352db 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java @@ -49,7 +49,7 @@ * *
Point
, LineString
, or
* Polygon
will be returned if the result contains a single
@@ -109,44 +109,44 @@
* report the location of the collapse. * *
- * Since {@link #equals(Object)} and {@link #hashCode()} are overridden,
+ * Since {@link #equals(Object)} and {@link #hashCode()} are overridden,
* Geometries can be used effectively in Java collections.
*
*@version 1.7
@@ -155,7 +155,7 @@ public abstract class Geometry
implements Cloneable, Comparable, Serializable
{
private static final long serialVersionUID = 8763622679187376702L;
-
+
static final int SORTINDEX_POINT = 0;
static final int SORTINDEX_MULTIPOINT = 1;
static final int SORTINDEX_LINESTRING = 2;
@@ -164,7 +164,7 @@ public abstract class Geometry
static final int SORTINDEX_POLYGON = 5;
static final int SORTINDEX_MULTIPOLYGON = 6;
static final int SORTINDEX_GEOMETRYCOLLECTION = 7;
-
+
private final static GeometryComponentFilter geometryChangedFilter = new GeometryComponentFilter() {
public void filter(Geometry geom) {
geom.geometryChangedAction();
@@ -262,12 +262,12 @@ public int getSRID() {
/**
* Sets the ID of the Spatial Reference System used by the Geometry
.
*
- * NOTE: This method should only be used for exceptional circumstances or - * for backwards compatibility. Normally the SRID should be set on the + * NOTE: This method should only be used for exceptional circumstances or + * for backwards compatibility. Normally the SRID should be set on the * {@link GeometryFactory} used to create the geometry. - * SRIDs set using this method will not be propagated to + * SRIDs set using this method will not be propagated to * geometries returned by constructive methods. - * + * * @see GeometryFactory */ public void setSRID(int SRID) { @@ -350,19 +350,19 @@ public PrecisionModel getPrecisionModel() { *@return null if this Geometry is empty */ public abstract Coordinate getCoordinate(); - + /** - * Returns an array containing the values of all the vertices for + * Returns an array containing the values of all the vertices for * this geometry. * If the geometry is a composite, the array will contain all the vertices * for the components, in the order in which the components occur in the geometry. *
- * In general, the array cannot be assumed to be the actual internal
+ * In general, the array cannot be assumed to be the actual internal
* storage for the vertices. Thus modifying the array
- * may not modify the geometry itself.
+ * may not modify the geometry itself.
* Use the {@link CoordinateSequence#setOrdinate} method
* (possibly on the components) to modify the underlying data.
- * If the coordinates are modified,
+ * If the coordinates are modified,
* {@link #geometryChanged} must be called afterwards.
*
*@return the vertices of this Geometry
@@ -461,7 +461,7 @@ public boolean isWithinDistance(Geometry geom, double distance)
/**
* Tests whether this is a rectangular {@link Polygon}.
- *
+ *
* @return true if the geometry is a rectangle.
*/
public boolean isRectangle()
@@ -510,7 +510,7 @@ public double getLength()
*/
public Point getCentroid()
{
- if (isEmpty())
+ if (isEmpty())
return factory.createPoint();
Coordinate centPt = Centroid.getCentroid(this);
return createPointFromInternalCoord(centPt, this);
@@ -535,15 +535,15 @@ public Point getInteriorPoint()
/**
* Returns the dimension of this geometry.
- * The dimension of a geometry is is the topological
+ * The dimension of a geometry is is the topological
* dimension of its embedding in the 2-D Euclidean plane.
* In the JTS spatial model, dimension values are in the set {0,1,2}.
*
- * Note that this is a different concept to the dimension of
- * the vertex {@link Coordinate}s.
+ * Note that this is a different concept to the dimension of
+ * the vertex {@link Coordinate}s.
* The geometry dimension can never be greater than the coordinate dimension.
- * For example, a 0-dimensional geometry (e.g. a Point)
- * may have a coordinate dimension of 3 (X,Y,Z).
+ * For example, a 0-dimensional geometry (e.g. a Point)
+ * may have a coordinate dimension of 3 (X,Y,Z).
*
*@return the topological dimension of this geometry.
*/
@@ -572,35 +572,35 @@ public Point getInteriorPoint()
public abstract int getBoundaryDimension();
/**
- * Gets a Geometry representing the envelope (bounding box) of
- * this Geometry
.
+ * Gets a Geometry representing the envelope (bounding box) of
+ * this Geometry
.
*
* If this Geometry
is:
*
Point
.
+ * Point
.
* Point
.
- * LineString
+ * LineString
* Polygon
whose vertices are (minx miny, maxx miny,
+ * Polygon
whose vertices are (minx miny, maxx miny,
* maxx maxy, minx maxy, minx miny).
* Geometry
.
- * If the geometry is empty, an empty Envelope
+ * If the geometry is empty, an empty Envelope
* is returned.
*
* The returned object is a copy of the one maintained internally,
- * to avoid aliasing issues.
+ * to avoid aliasing issues.
* For best performance, clients which access this
* envelope frequently should cache the return value.
*
@@ -616,7 +616,7 @@ public Envelope getEnvelopeInternal() {
/**
* Notifies this geometry that its coordinates have been changed by an external
- * party (for example, via a {@link CoordinateFilter}).
+ * party (for example, via a {@link CoordinateFilter}).
* When this method is called the geometry will flush
* and/or update any derived information it has cached (such as its {@link Envelope} ).
* The operation is applied to all component Geometries.
@@ -629,7 +629,7 @@ public void geometryChanged() {
* Notifies this Geometry that its Coordinates have been changed by an external
* party. When #geometryChanged is called, this method will be called for
* this Geometry and its component Geometries.
- *
+ *
* @see #apply(GeometryComponentFilter)
*/
protected void geometryChangedAction() {
@@ -642,7 +642,7 @@ protected void geometryChangedAction() {
* The disjoint
predicate has the following equivalent definitions:
*
[FF*FF****]
* ! g.intersects(this) = true
* disjoint
is the inverse of intersects
)
@@ -664,7 +664,7 @@ public boolean disjoint(Geometry g) {
*
* The touches
predicate has the following equivalent definitions:
*
false
,
* since points have only interiors.
* This predicate is symmetric.
- *
+ *
*
*@param g the Geometry
with which to compare this Geometry
*@return true
if the two Geometry
s touch;
@@ -795,7 +795,7 @@ public boolean crosses(Geometry g) {
* [T*F**F***]
* g.contains(this) = true
* within
is the converse of {@link #contains})
@@ -805,7 +805,7 @@ public boolean crosses(Geometry g) {
* In other words, if a geometry A is a subset of
* the points in the boundary of a geometry B, A.within(B) = false
* (As a concrete example, take A to be a LineString which lies in the boundary of a Polygon B.)
- * For a predicate with similar behaviour but avoiding
+ * For a predicate with similar behaviour but avoiding
* this subtle limitation, see {@link #coveredBy}.
*
*@param g the Geometry
with which to compare this Geometry
@@ -827,7 +827,7 @@ public boolean within(Geometry g) {
* [T*****FF*]
* g.within(this) = true
@@ -837,7 +837,7 @@ public boolean within(Geometry g) {
* contain their boundary". In other words, if a geometry A is a subset of
* the points in the boundary of a geometry B, B.contains(A) = false
.
* (As a concrete example, take A to be a LineString which lies in the boundary of a Polygon B.)
- * For a predicate with similar behaviour but avoiding
+ * For a predicate with similar behaviour but avoiding
* this subtle limitation, see {@link #covers}.
*
*@param g the Geometry
with which to compare this Geometry
@@ -852,7 +852,7 @@ public boolean contains(Geometry g) {
return false;
}
// optimization - P cannot contain a non-zero-length L
- // Note that a point can contain a zero-length lineal geometry,
+ // Note that a point can contain a zero-length lineal geometry,
// since the line has no boundary due to Mod-2 Boundary Rule
if (g.getDimension() == 1 && getDimension() < 1 && g.getLength() > 0.0) {
return false;
@@ -905,7 +905,7 @@ public boolean overlaps(Geometry g) {
* [T*****FF*]
* [*T****FF*]
* [***T**FF*]
@@ -1025,15 +1025,15 @@ public IntersectionMatrix relate(Geometry g) {
}
/**
- * Tests whether this geometry is
+ * Tests whether this geometry is
* topologically equal to the argument geometry.
* * This method is included for backward compatibility reasons. * It has been superseded by the {@link #equalsTopo(Geometry)} method, * which has been named to clearly denote its functionality. *
- * This method should NOT be confused with the method
- * {@link #equals(Object)}, which implements
+ * This method should NOT be confused with the method
+ * {@link #equals(Object)}, which implements
* an exact equality comparison.
*
*@param g the Geometry
with which to compare this Geometry
@@ -1055,20 +1055,20 @@ public boolean equals(Geometry g) {
*
T*F**FFF*
+ * the pattern T*F**FFF*
* * T*F * **F * FF* **
Geometry
with which to compare this Geometry
*@return true
if the two Geometry
s are topologically equal
*
- *@see #equalsExact(Geometry)
+ *@see #equalsExact(Geometry)
*/
public boolean equalsTopo(Geometry g)
{
@@ -1077,31 +1077,31 @@ public boolean equalsTopo(Geometry g)
return false;
return relate(g).isEquals(getDimension(), g.getDimension());
}
-
+
/**
* Tests whether this geometry is structurally and numerically equal
* to a given Object
.
- * If the argument Object
is not a Geometry
,
+ * If the argument Object
is not a Geometry
,
* the result is false
.
* Otherwise, the result is computed using
* {@link #equalsExact(Geometry)}.
*
* This method is provided to fulfill the Java contract
- * for value-based object equality.
- * In conjunction with {@link #hashCode()}
- * it provides semantics which are most useful
+ * for value-based object equality.
+ * In conjunction with {@link #hashCode()}
+ * it provides semantics which are most useful
* for using
* Geometry
s as keys and values in Java collections.
*
* Note that to produce the expected result the input geometries
- * should be in normal form. It is the caller's
+ * should be in normal form. It is the caller's
* responsibility to perform this where required
* (using {@link Geometry#norm()}
* or {@link #normalize()} as appropriate).
- *
+ *
* @param o the Object to compare
- * @return true if this geometry is exactly equal to the argument
- *
+ * @return true if this geometry is exactly equal to the argument
+ *
* @see #equalsExact(Geometry)
* @see #hashCode()
* @see #norm()
@@ -1113,17 +1113,17 @@ public boolean equals(Object o)
Geometry g = (Geometry) o;
return equalsExact(g);
}
-
+
/**
* Gets a hash code for the Geometry.
- *
+ *
* @return an integer value suitable for use as a hashcode
*/
public int hashCode()
{
return getEnvelopeInternal().hashCode();
}
-
+
public String toString() {
return toText();
}
@@ -1144,25 +1144,25 @@ public String toText() {
* Computes a buffer area around this geometry having the given width. The
* buffer of a Geometry is the Minkowski sum or difference of the geometry
* with a disc of radius abs(distance)
.
- *
- * Mathematically-exact buffer area boundaries can contain circular arcs. + *
+ * Mathematically-exact buffer area boundaries can contain circular arcs.
* To represent these arcs using linear geometry they must be approximated with line segments.
- * The buffer geometry is constructed using 8 segments per quadrant to approximate
+ * The buffer geometry is constructed using 8 segments per quadrant to approximate
* the circular arcs.
* The end cap style is CAP_ROUND
.
*
* The buffer operation always returns a polygonal result. The negative or * zero-distance buffer of lines and points is always an empty {@link Polygon}. * This is also the result for the buffers of degenerate (zero-area) polygons. - * + * * @param distance * the width of the buffer (may be positive, negative or 0) * @return a polygonal geometry representing the buffer region (which may be * empty) - * + * * @throws TopologyException * if a robustness error occurs - * + * * @see #buffer(double, int) * @see #buffer(double, int, int) */ @@ -1174,7 +1174,7 @@ public Geometry buffer(double distance) { * Computes a buffer area around this geometry having the given width and with * a specified accuracy of approximation for circular arcs. *
- * Mathematically-exact buffer area boundaries can contain circular arcs.
+ * Mathematically-exact buffer area boundaries can contain circular arcs.
* To represent these arcs
* using linear geometry they must be approximated with line segments. The
* quadrantSegments
argument allows controlling the accuracy of
@@ -1184,7 +1184,7 @@ public Geometry buffer(double distance) {
* The buffer operation always returns a polygonal result. The negative or
* zero-distance buffer of lines and points is always an empty {@link Polygon}.
* This is also the result for the buffers of degenerate (zero-area) polygons.
- *
+ *
* @param distance
* the width of the buffer (may be positive, negative or 0)
* @param quadrantSegments
@@ -1192,10 +1192,10 @@ public Geometry buffer(double distance) {
* circle
* @return a polygonal geometry representing the buffer region (which may be
* empty)
- *
+ *
* @throws TopologyException
* if a robustness error occurs
- *
+ *
* @see #buffer(double)
* @see #buffer(double, int, int)
*/
@@ -1278,24 +1278,34 @@ public Geometry convexHull() {
/**
* Computes a new geometry which has all component coordinate sequences
* in reverse order (opposite orientation) to this one.
- *
+ *
* @return a reversed geometry
*/
- public abstract Geometry reverse();
-
+ public Geometry reverse() {
+
+ Geometry res = reverseInternal();
+ if (this.envelope != null)
+ res.envelope = this.envelope.copy();
+ res.setSRID(getSRID());
+
+ return res;
+ }
+
+ protected abstract Geometry reverseInternal();
+
/**
* Computes a Geometry
representing the point-set which is
* common to both this Geometry
and the other
Geometry.
*
* The intersection of two geometries of different dimension produces a result * geometry of dimension less than or equal to the minimum dimension of the input - * geometries. + * geometries. * The result geometry may be a heterogeneous {@link GeometryCollection}. * If the result is empty, it is an atomic geometry * with the dimension of the lowest input dimension. *
* Intersection of {@link GeometryCollection}s is supported - * only for homogeneous collection types. + * only for homogeneous collection types. *
* Non-empty heterogeneous {@link GeometryCollection} arguments are not supported.
*
@@ -1310,7 +1320,7 @@ public Geometry intersection(Geometry other)
* TODO: MD - add optimization for P-A case using Point-In-Polygon
*/
// special case: if one input is empty ==> empty
- if (this.isEmpty() || other.isEmpty())
+ if (this.isEmpty() || other.isEmpty())
return OverlayOp.createEmptyResult(OverlayOp.INTERSECTION, this, other, factory);
// compute for GCs
@@ -1334,13 +1344,13 @@ public Geometry map(Geometry g) {
}
/**
- * Computes a Geometry
representing the point-set
+ * Computes a Geometry
representing the point-set
* which is contained in both this
* Geometry
and the other
Geometry.
*
* The union of two geometries of different dimension produces a result * geometry of dimension equal to the maximum dimension of the input - * geometries. + * geometries. * The result geometry may be a heterogeneous * {@link GeometryCollection}. * If the result is empty, it is an atomic geometry @@ -1351,12 +1361,12 @@ public Geometry map(Geometry g) { * "noding" means that there will be a node or endpoint in the result for * every endpoint or line segment crossing in the input. "Dissolving" means * that any duplicate (i.e. coincident) line segments or portions of line - * segments will be reduced to a single line segment in the result. + * segments will be reduced to a single line segment in the result. * If merged linework is required, the {@link LineMerger} * class can be used. *
* Non-empty {@link GeometryCollection} arguments are not supported.
- *
+ *
* @param other
* the Geometry
with which to compute the union
* @return a point-set combining the points of this Geometry
and the
@@ -1373,14 +1383,14 @@ public Geometry union(Geometry other)
if (this.isEmpty() || other.isEmpty()) {
if (this.isEmpty() && other.isEmpty())
return OverlayOp.createEmptyResult(OverlayOp.UNION, this, other, factory);
-
+
// special case: if either input is empty ==> other input
if (this.isEmpty()) return other.copy();
if (other.isEmpty()) return copy();
}
-
+
// TODO: optimize if envelopes of geometries do not intersect
-
+
checkNotGeometryCollection(this);
checkNotGeometryCollection(other);
return SnapIfNeededOverlayOp.overlayOp(this, other, OverlayOp.UNION);
@@ -1388,8 +1398,8 @@ public Geometry union(Geometry other)
/**
* Computes a Geometry
representing the closure of the point-set
- * of the points contained in this Geometry
that are not contained in
- * the other
Geometry.
+ * of the points contained in this Geometry
that are not contained in
+ * the other
Geometry.
*
* If the result is empty, it is an atomic geometry
* with the dimension of the left-hand input.
@@ -1416,10 +1426,10 @@ public Geometry difference(Geometry other)
/**
* Computes a Geometry
representing the closure of the point-set
- * which is the union of the points in this Geometry
which are not
+ * which is the union of the points in this Geometry
which are not
* contained in the other
Geometry,
* with the points in the other
Geometry not contained in this
- * Geometry
.
+ * Geometry
.
* If the result is empty, it is an atomic geometry
* with the dimension of the highest input dimension.
*
@@ -1439,7 +1449,7 @@ public Geometry symDifference(Geometry other) // both empty - check dimensions if (this.isEmpty() && other.isEmpty()) return OverlayOp.createEmptyResult(OverlayOp.SYMDIFFERENCE, this, other, factory); - + // special case: if either input is empty ==> result = other arg if (this.isEmpty()) return other.copy(); if (other.isEmpty()) return copy(); @@ -1451,30 +1461,30 @@ public Geometry symDifference(Geometry other) } /** - * Computes the union of all the elements of this geometry. + * Computes the union of all the elements of this geometry. *
* This method supports - * {@link GeometryCollection}s + * {@link GeometryCollection}s * (which the other overlay operations currently do not). *
* The result obeys the following contract: *
Geometry
s are exactly equal,
* up to a specified distance tolerance.
@@ -1486,7 +1496,7 @@ public Geometry union() {
* within the given tolerance distance, in exactly the same order.
* GeometryFactory
, the SRID
,
+ * test the values of the GeometryFactory
, the SRID
,
* or the userData
fields.
*
* To properly test equality between different geometries,
@@ -1497,7 +1507,7 @@ public Geometry union() {
* are considered equal
* @return true
if this and the other Geometry
* have identical structure and point values, up to the distance tolerance.
- *
+ *
* @see #equalsExact(Geometry)
* @see #normalize()
* @see #norm()
@@ -1518,7 +1528,7 @@ public Geometry union() {
* (such as using geometries as keys in collections).
*
* This method does not
- * test the values of the GeometryFactory
, the SRID
,
+ * test the values of the GeometryFactory
, the SRID
,
* or the userData
fields.
*
* To properly test equality between different geometries,
@@ -1527,13 +1537,13 @@ public Geometry union() {
*@param other the Geometry
with which to compare this Geometry
*@return true
if this and the other Geometry
* have identical structure and point values.
- *
+ *
* @see #equalsExact(Geometry, double)
* @see #normalize()
* @see #norm()
*/
- public boolean equalsExact(Geometry other)
- {
+ public boolean equalsExact(Geometry other)
+ {
return this == other || equalsExact(other, 0);
}
@@ -1544,11 +1554,11 @@ public boolean equalsExact(Geometry other)
* versions of both geometries before computing
* {@link #equalsExact(Geometry)}.
*
- * This method is relatively expensive to compute.
- * For maximum performance, the client
+ * This method is relatively expensive to compute.
+ * For maximum performance, the client
* should instead perform normalization on the individual geometries
* at an appropriate point during processing.
- *
+ *
* @param g a Geometry
* @return true if the input geometries are exactly equal in their normalized form
*/
@@ -1557,13 +1567,13 @@ public boolean equalsNorm(Geometry g)
if (g == null) return false;
return norm().equalsExact(g.norm());
}
-
+
/**
* Performs an operation with or on this Geometry
's
- * coordinates.
+ * coordinates.
* If this method modifies any coordinate values,
- * {@link #geometryChanged} must be called to update the geometry state.
+ * {@link #geometryChanged} must be called to update the geometry state.
* Note that you cannot use this method to
* modify this Geometry if its underlying CoordinateSequence's #get method
* returns a copy of the Coordinate, rather than the actual Coordinate stored
@@ -1576,8 +1586,8 @@ public boolean equalsNorm(Geometry g)
/**
* Performs an operation on the coordinates in this Geometry
's
- * {@link CoordinateSequence}s.
- * If the filter reports that a coordinate value has been changed,
+ * {@link CoordinateSequence}s.
+ * If the filter reports that a coordinate value has been changed,
* {@link #geometryChanged} will be called automatically.
*
*@param filter the filter to apply
@@ -1625,7 +1635,7 @@ public Object clone() {
return null;
}
}
-
+
/**
* Creates a deep copy of this {@link Geometry} object.
* Coordinate sequences contained in it are copied.
@@ -1634,7 +1644,7 @@ public Object clone() {
*
* NOTE: the userData object reference (if present) is copied,
* but the value itself is not copied.
- * If a deep copy is required this must be performed by the caller.
+ * If a deep copy is required this must be performed by the caller.
*
* @return a deep copy of this geometry
*/
@@ -1642,17 +1652,17 @@ public Geometry copy() {
Geometry copy = copyInternal();
copy.envelope = envelope == null ? null : envelope.copy();
copy.SRID = this.SRID;
- copy.userData = this.userData;
+ copy.userData = this.userData;
return copy;
}
-
+
/**
* An internal method to copy subclass-specific geometry data.
- *
+ *
* @return a copy of the target geometry object.
*/
protected abstract Geometry copyInternal();
-
+
/**
* Converts this Geometry
to normal form (or
* canonical form ). Normal form is a unique representation for Geometry
@@ -1672,8 +1682,8 @@ public Geometry copy() {
/**
* Creates a new Geometry which is a normalized
- * copy of this Geometry.
- *
+ * copy of this Geometry.
+ *
* @return a normalized copy of this geometry.
* @see #normalize()
*/
@@ -1683,7 +1693,7 @@ public Geometry norm()
copy.normalize();
return copy;
}
-
+
/**
* Returns whether this Geometry
is greater than, equal to,
* or less than another Geometry
.
@@ -1807,7 +1817,7 @@ protected static void checkNotGeometryCollection(Geometry g) {
/**
* Tests whether this is an instance of a general {@link GeometryCollection},
* rather than a homogeneous subclass.
- *
+ *
* @return true if this is a heterogeneous GeometryCollection
*/
protected boolean isGeometryCollection()
@@ -1890,7 +1900,7 @@ protected boolean equal(Coordinate a, Coordinate b, double tolerance) {
if (tolerance == 0) { return a.equals(b); }
return a.distance(b) <= tolerance;
}
-
+
abstract protected int getSortIndex();
private Point createPointFromInternalCoord(Coordinate coord, Geometry exemplar)
diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java b/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java
index 216bdbabab..78b9c8b9b6 100644
--- a/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java
+++ b/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java
@@ -13,7 +13,9 @@
*/
package org.locationtech.jts.geom;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.TreeSet;
import org.locationtech.jts.util.Assert;
@@ -22,7 +24,7 @@
/**
* Models a collection of {@link Geometry}s of
* arbitrary type and dimension.
- *
+ *
*
*@version 1.7
*/
@@ -218,7 +220,7 @@ public void apply(GeometryComponentFilter filter) {
public Object clone() {
return copy();
}
-
+
protected GeometryCollection copyInternal() {
Geometry[] geometries = new Geometry[this.geometries.length];
for (int i = 0; i < geometries.length; i++) {
@@ -266,26 +268,31 @@ protected int compareToSameClass(Object o, CoordinateSequenceComparator comp) {
return 0;
}
-
+
protected int getSortIndex() {
return Geometry.SORTINDEX_GEOMETRYCOLLECTION;
}
-
+
/**
* Creates a {@link GeometryCollection} with
* every component reversed.
* The order of the components in the collection are not reversed.
*
* @return a {@link GeometryCollection} in the reverse order
+ * @deprecated
*/
- public Geometry reverse()
+ public Geometry reverse() {
+ return super.reverse();
+ }
+
+ protected Geometry reverseInternal()
{
- int n = geometries.length;
- Geometry[] revGeoms = new Geometry[n];
- for (int i = 0; i < geometries.length; i++) {
- revGeoms[i] = geometries[i].reverse();
+ int numGeometries = geometries.length;
+ Collection
- * A linestring must have either 0 or 2 or more points.
- * If these conditions are not met, the constructors throw
+ * Linestrings with exactly two identical points are invalid.
+ *
+ * A linestring must have either 0 or 2 or more points.
+ * If these conditions are not met, the constructors throw
* an {@link IllegalArgumentException}
*
*@version 1.7
*/
-public class LineString
- extends Geometry
+public class LineString
+ extends Geometry
implements Lineal
{
private static final long serialVersionUID = 3110669828065365560L;
@@ -62,9 +62,9 @@ public LineString(Coordinate points[], PrecisionModel precisionModel, int SRID)
/**
* Constructs a
- * A ring must have either 0 or 4 or more points.
+ * A ring must have either 0 or 4 or more points.
* The first and last points must be equal (in 2D).
- * If these conditions are not met, the constructors throw
+ * If these conditions are not met, the constructors throw
* an {@link IllegalArgumentException}
*
* @version 1.7
@@ -35,7 +35,7 @@ public class LinearRing extends LineString
* Empty rings with 0 vertices are also valid.
*/
public static final int MINIMUM_VALID_SIZE = 4;
-
+
private static final long serialVersionUID = -4261142084085851829L;
/**
@@ -50,7 +50,7 @@ public class LinearRing extends LineString
*@param SRID the ID of the Spatial Reference System used by this
*
- * As per the OGC SFS specification,
- * the Polygons in a MultiPolygon may not overlap,
+ * As per the OGC SFS specification,
+ * the Polygons in a MultiPolygon may not overlap,
* and may only touch at single points.
* This allows the topological point-set semantics
* to be well-defined.
- *
+ *
*
*@version 1.7
*/
-public class MultiPolygon
- extends GeometryCollection
+public class MultiPolygon
+ extends GeometryCollection
implements Polygonal
{
private static final long serialVersionUID = -551033529766975875L;
@@ -83,7 +83,7 @@ public boolean isSimple() {
return true;
}
*/
-
+
/**
* Computes the boundary of this geometry
*
@@ -112,24 +112,19 @@ public boolean equalsExact(Geometry other, double tolerance) {
}
return super.equalsExact(other, tolerance);
}
-
+
/**
* Creates a {@link MultiPolygon} with
* every component reversed.
* The order of the components in the collection are not reversed.
*
* @return a MultiPolygon in the reverse order
+ * @deprecated
*/
- public Geometry reverse()
- {
- int n = geometries.length;
- Polygon[] revGeoms = new Polygon[n];
- for (int i = 0; i < geometries.length; i++) {
- revGeoms[i] = (Polygon) geometries[i].reverse();
- }
- return getFactory().createMultiPolygon(revGeoms);
+ public Geometry reverse() {
+ return super.reverse();
}
-
+
protected MultiPolygon copyInternal() {
Polygon[] polygons = new Polygon[this.geometries.length];
for (int i = 0; i < polygons.length; i++) {
diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/Point.java b/modules/core/src/main/java/org/locationtech/jts/geom/Point.java
index 5f7fac0aef..abfb53ca65 100644
--- a/modules/core/src/main/java/org/locationtech/jts/geom/Point.java
+++ b/modules/core/src/main/java/org/locationtech/jts/geom/Point.java
@@ -20,13 +20,13 @@
*
* A
- * The polygon model conforms to the assertions specified in the
+ * The polygon model conforms to the assertions specified in the
* OpenGIS Simple Features
* Specification for SQL.
*
@@ -37,15 +37,15 @@
* (i.e. are closed and do not self-intersect)
* LineString
.
* A LineString consists of a sequence of two or more vertices,
* along with all points along the linearly-interpolated curves
- * (line segments) between each
+ * (line segments) between each
* pair of consecutive vertices.
* Consecutive vertices may be equal.
- * The line segments in the line may intersect each other (in other words,
+ * The line segments in the line may intersect each other (in other words,
* the linestring may "curl back" in itself and self-intersect.
- * Linestrings with exactly two identical points are invalid.
- * LineString
with the given points.
- *
+ *
*@param points the points of the linestring, or null
- * to create the empty geometry.
+ * to create the empty geometry.
* @throws IllegalArgumentException if too few points are provided
*/
public LineString(CoordinateSequence points, GeometryFactory factory) {
@@ -78,7 +78,7 @@ private void init(CoordinateSequence points)
points = getFactory().getCoordinateSequenceFactory().create(new Coordinate[]{});
}
if (points.size() == 1) {
- throw new IllegalArgumentException("Invalid number of points in LineString (found "
+ throw new IllegalArgumentException("Invalid number of points in LineString (found "
+ points.size() + " - must be 0 or >= 2)");
}
this.points = points;
@@ -179,13 +179,17 @@ public Geometry getBoundary() {
* order of this objects
*
* @return a {@link LineString} with coordinates in the reverse order
+ * @deprecated
*/
- public Geometry reverse()
+ public Geometry reverse() {
+ return super.reverse();
+ }
+
+ protected Geometry reverseInternal()
{
CoordinateSequence seq = points.copy();
CoordinateSequences.reverse(seq);
- LineString revLine = getFactory().createLineString(seq);
- return revLine;
+ return getFactory().createLineString(seq);
}
/**
@@ -233,7 +237,7 @@ public void apply(CoordinateFilter filter) {
}
}
- public void apply(CoordinateSequenceFilter filter)
+ public void apply(CoordinateSequenceFilter filter)
{
if (points.size() == 0)
return;
@@ -264,7 +268,7 @@ public void apply(GeometryComponentFilter filter) {
public Object clone() {
return copy();
}
-
+
protected LineString copyInternal() {
return new LineString(points.copy(), factory);
}
@@ -322,7 +326,7 @@ protected int compareToSameClass(Object o, CoordinateSequenceComparator comp)
LineString line = (LineString) o;
return comp.compare(this.points, line.points);
}
-
+
protected int getSortIndex() {
return Geometry.SORTINDEX_LINESTRING;
}
diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/LinearRing.java b/modules/core/src/main/java/org/locationtech/jts/geom/LinearRing.java
index 005ae74315..f8389645b1 100644
--- a/modules/core/src/main/java/org/locationtech/jts/geom/LinearRing.java
+++ b/modules/core/src/main/java/org/locationtech/jts/geom/LinearRing.java
@@ -21,9 +21,9 @@
* and the interior of the ring must not self-intersect.
* Either orientation of the ring is allowed.
* LinearRing
* @throws IllegalArgumentException if the ring is not closed, or has too few points
- *
+ *
* @deprecated Use GeometryFactory instead
*/
public LinearRing(Coordinate points[], PrecisionModel precisionModel,
@@ -76,7 +76,7 @@ private LinearRing(Coordinate points[], GeometryFactory factory) {
*
*@param points a sequence points forming a closed and simple linestring, or
* null
to create the empty geometry.
- *
+ *
* @throws IllegalArgumentException if the ring is not closed, or has too few points
*
*/
@@ -90,7 +90,7 @@ private void validateConstruction() {
throw new IllegalArgumentException("Points of LinearRing do not form a closed linestring");
}
if (getCoordinateSequence().size() >= 1 && getCoordinateSequence().size() < MINIMUM_VALID_SIZE) {
- throw new IllegalArgumentException("Invalid number of points in LinearRing (found "
+ throw new IllegalArgumentException("Invalid number of points in LinearRing (found "
+ getCoordinateSequence().size() + " - must be 0 or >= 4)");
}
}
@@ -108,7 +108,7 @@ public int getBoundaryDimension() {
/**
* Tests whether this ring is closed.
* Empty rings are closed by definition.
- *
+ *
* @return true if this ring is closed
*/
public boolean isClosed() {
@@ -123,20 +123,24 @@ public boolean isClosed() {
public String getGeometryType() {
return "LinearRing";
}
-
+
protected int getSortIndex() {
return Geometry.SORTINDEX_LINEARRING;
}
-
+
protected LinearRing copyInternal() {
return new LinearRing(points.copy(), factory);
}
+ /** @deprecated */
public Geometry reverse()
{
+ return super.reverse();
+ }
+
+ public Geometry reverseInternal() {
CoordinateSequence seq = points.copy();
CoordinateSequences.reverse(seq);
- LinearRing rev = getFactory().createLinearRing(seq);
- return rev;
+ return getFactory().createLinearRing(seq);
}
}
diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java b/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java
index 15ce502a0b..818968ca61 100644
--- a/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java
+++ b/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java
@@ -20,7 +20,7 @@
*
*@version 1.7
*/
-public class MultiLineString
+public class MultiLineString
extends GeometryCollection
implements Lineal
{
@@ -102,17 +102,12 @@ public Geometry getBoundary()
* are reversed.
*
* @return a {@link MultiLineString} in the reverse order
+ * @deprecated
*/
- public Geometry reverse()
- {
- int nLines = geometries.length;
- LineString[] revLines = new LineString[nLines];
- for (int i = 0; i < geometries.length; i++) {
- revLines[nLines - 1 - i] = (LineString)geometries[i].reverse();
- }
- return getFactory().createMultiLineString(revLines);
+ public Geometry reverse() {
+ return super.reverse();
}
-
+
protected MultiLineString copyInternal() {
LineString[] lineStrings = new LineString[this.geometries.length];
for (int i = 0; i < lineStrings.length; i++) {
diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java b/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java
index 67df633248..bb3bdd79c7 100644
--- a/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java
+++ b/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java
@@ -18,17 +18,17 @@
/**
* Models a collection of {@link Polygon}s.
* Point
is topologically valid if and only if:
*
- *
- *
+ *
*@version 1.7
*/
-public class Point
+public class Point
extends Geometry
implements Puntal
{
@@ -158,7 +158,7 @@ public void apply(CoordinateFilter filter) {
filter.filter(getCoordinate());
}
- public void apply(CoordinateSequenceFilter filter)
+ public void apply(CoordinateSequenceFilter filter)
{
if (isEmpty())
return;
@@ -185,19 +185,24 @@ public void apply(GeometryComponentFilter filter) {
public Object clone() {
return copy();
}
-
+
protected Point copyInternal() {
return new Point(coordinates.copy(), factory);
}
- public Geometry reverse()
+ /** @deprecated */
+ public Geometry reverse() {
+ return super.reverse();
+ }
+
+ protected Geometry reverseInternal()
{
- return copy();
+ return getFactory().createPoint(coordinates.copy());
}
-
- public void normalize()
- {
- // a Point is always in normalized form
+
+ public void normalize()
+ {
+ // a Point is always in normalized form
}
protected int compareToSameClass(Object other) {
@@ -210,7 +215,7 @@ protected int compareToSameClass(Object other, CoordinateSequenceComparator comp
Point point = (Point) other;
return comp.compare(this.coordinates, point.coordinates);
}
-
+
protected int getSortIndex() {
return Geometry.SORTINDEX_POINT;
}
diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/Polygon.java b/modules/core/src/main/java/org/locationtech/jts/geom/Polygon.java
index 2732372006..f3c8d10eb9 100644
--- a/modules/core/src/main/java/org/locationtech/jts/geom/Polygon.java
+++ b/modules/core/src/main/java/org/locationtech/jts/geom/Polygon.java
@@ -21,12 +21,12 @@
/**
* Represents a polygon with linear edges, which may include holes.
- * The outer boundary (shell)
+ * The outer boundary (shell)
* and inner boundaries (holes) of the polygon are represented by {@link LinearRing}s.
* The boundary rings of the polygon may have any orientation.
* Polygons are closed, simple geometries by definition.
* NaN
X or Y ordinate)
*