(0);
@@ -1150,7 +1149,7 @@ static boolean _cutterTangents(boolean bConsiderTouch, EditShape shape,
return _cutterStartTangents(bConsiderTouch, shape, cutEvents,
icutEvent, tangent0, tangent1);
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
static boolean _cutterEndTangents(boolean bConsiderTouch, EditShape shape,
@@ -1423,6 +1422,6 @@ static boolean _cutteeTangents(EditShape shape,
return false;
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
diff --git a/src/com/esri/core/geometry/ECoordinate.java b/src/main/java/com/esri/core/geometry/ECoordinate.java
similarity index 96%
rename from src/com/esri/core/geometry/ECoordinate.java
rename to src/main/java/com/esri/core/geometry/ECoordinate.java
index cfc3146b..5bcf0460 100644
--- a/src/com/esri/core/geometry/ECoordinate.java
+++ b/src/main/java/com/esri/core/geometry/ECoordinate.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -27,6 +27,18 @@ class ECoordinate {
private double m_value;
private double m_eps;
+ ECoordinate() {
+ set(0.0, 0.0);
+ }
+
+ ECoordinate(double v) {
+ set(v);
+ }
+
+ ECoordinate(ECoordinate v) {
+ set(v);
+ }
+
double epsCoordinate() {
return NumberUtils.doubleEps();
}
@@ -160,7 +172,7 @@ void mul(double v) {
}
void mul(ECoordinate v_1, ECoordinate v_2) {
- double r = Math.abs(v_1.m_value) * Math.abs(v_2.m_value);
+ double r = v_1.m_value * v_2.m_value;
m_eps = v_1.m_eps * Math.abs(v_2.m_value) + v_2.m_eps
* Math.abs(v_1.m_value) + v_1.m_eps * v_2.m_eps
+ epsCoordinate() * Math.abs(r);
@@ -189,7 +201,7 @@ void div(ECoordinate divis) {
if (divis.m_eps > 0.01 * fabsdivis) {// more accurate error calculation
// for very inaccurate divisor
double rr = divis.m_eps / fabsdivis;
- e *= (1. + (1. + rr) * rr);
+ e *= (1.0 + (1.0 + rr) * rr);
}
m_value = r;
m_eps = e + epsCoordinate() * Math.abs(r);
@@ -226,7 +238,7 @@ void sqrt() {
if (m_value >= 0) { // assume non-negative input
r = Math.sqrt(m_value);
- if (m_value > 10. * m_eps) {
+ if (m_value > 10.0 * m_eps) {
dr = 0.5 * m_eps / r;
} else {
dr = (m_value > m_eps) ? r - Math.sqrt(m_value - m_eps) : Math
diff --git a/src/com/esri/core/geometry/EditShape.java b/src/main/java/com/esri/core/geometry/EditShape.java
similarity index 93%
rename from src/com/esri/core/geometry/EditShape.java
rename to src/main/java/com/esri/core/geometry/EditShape.java
index 565dd98f..ebbfb18d 100644
--- a/src/com/esri/core/geometry/EditShape.java
+++ b/src/main/java/com/esri/core/geometry/EditShape.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,12 +25,14 @@
import java.util.ArrayList;
+import com.esri.core.geometry.Geometry.GeometryType;
+
/**
* A helper geometry structure that can store MultiPoint, Polyline, Polygon
* geometries in linked lists. It allows constant time manipulation of geometry
* vertices.
*/
-class EditShape {
+final class EditShape {
interface PathFlags_ {
static final int closedPath = 1;
static final int exteriorPath = 2;
@@ -204,7 +206,7 @@ int newPath_(int geom) {
// m_path_index_list.set(index + 4, -1);//first vertex handle
// m_path_index_list.set(index + 5, -1);//last vertex handle
m_path_index_list.setField(index, 6, 0);// path flags
- m_path_index_list.setField(index, 7, geom);// geometry handle
+ setPathGeometry_(index, geom);
if (pindex >= m_path_areas.size()) {
int sz = pindex < 16 ? 16 : (pindex * 3) / 2;
m_path_areas.resize(sz);
@@ -331,10 +333,25 @@ Point getHelperPoint_() {
m_helper_point = new Point(m_vertices.getDescription());
return m_helper_point;
}
+
+ void setFillRule(int geom, int rule) {
+ int t = m_geometry_index_list.getField(geom, 2);
+ t &= ~(0x8000000);
+ t |= rule == Polygon.FillRule.enumFillRuleWinding ? 0x8000000 : 0;
+ m_geometry_index_list.setField(geom, 2, t);//fill rule combined with geometry type
+ }
+ int getFillRule(int geom) {
+ int t = m_geometry_index_list.getField(geom, 2);
+ return (t & 0x8000000) != 0 ? Polygon.FillRule.enumFillRuleWinding : Polygon.FillRule.enumFillRuleOddEven;
+ }
+
int addMultiPath_(MultiPath multi_path) {
int newgeom = createGeometry(multi_path.getType(),
multi_path.getDescription());
+ if (multi_path.getType() == Geometry.Type.Polygon)
+ setFillRule(newgeom, ((Polygon)multi_path).getFillRule());
+
appendMultiPath_(newgeom, multi_path);
return newgeom;
}
@@ -419,7 +436,7 @@ void splitSegmentForward_(int origin_vertex,
SegmentIntersector intersector, int intersector_index) {
int last_vertex = getNextVertex(origin_vertex);
if (last_vertex == -1)
- throw new IllegalArgumentException("internal error");
+ throw GeometryException.GeometryInternalError();
Point point = getHelperPoint_();
int path = getPathFromVertex(origin_vertex);
int vertex = origin_vertex;
@@ -466,7 +483,8 @@ void splitSegmentBackward_(int origin_vertex,
SegmentIntersector intersector, int intersector_index) {
int last_vertex = getNextVertex(origin_vertex);
if (last_vertex == -1)
- throw new IllegalArgumentException("internal error");
+ throw GeometryException.GeometryInternalError();
+
Point point = getHelperPoint_();
int path = getPathFromVertex(origin_vertex);
int vertex = origin_vertex;
@@ -561,7 +579,7 @@ int addGeometry(Geometry geometry) {
if (gt == Geometry.Type.MultiPoint)
return addMultiPoint_((MultiPoint) geometry);
- throw new IllegalArgumentException("internal error");
+ throw GeometryException.GeometryInternalError();
}
// Append a Geometry to the given geometry of the Edit_shape
@@ -575,7 +593,7 @@ void appendGeometry(int dstGeometry, Geometry srcGeometry) {
return;
}
- throw new IllegalArgumentException("internal error");
+ throw GeometryException.GeometryInternalError();
}
// Adds a path
@@ -584,6 +602,8 @@ int addPathFromMultiPath(MultiPath multi_path, int ipath, boolean as_polygon) {
: Geometry.Type.Polyline, multi_path.getDescription());
MultiPathImpl mp_impl = (MultiPathImpl) multi_path._getImpl();
+ if (multi_path.getPathSize(ipath) < 2)
+ return newgeom; //return empty geometry
// m_vertices->reserve_rounded(m_vertices->get_point_count() +
// multi_path.get_path_size(ipath));//ensure reallocation happens by
@@ -698,7 +718,7 @@ Geometry getGeometry(int geometry) {
mp_impl.setPathFlagsStreamRef(pathFlags);
mp_impl.setPathStreamRef(parts);
- mp_impl.notifyModified(DirtyFlags.dirtyAll);
+ mp_impl.notifyModified(MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
} else if (gt == Geometry.GeometryType.MultiPoint) {
MultiPointImpl mp_impl = (MultiPointImpl) geom._getImpl();
VertexDescription description = geom.getDescription();
@@ -731,7 +751,7 @@ Geometry getGeometry(int geometry) {
mp_impl.setAttributeStreamRef(semantics, dst_stream);
}
- mp_impl.notifyModified(DirtyFlags.dirtyAll);
+ mp_impl.notifyModified(MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
} else {
assert (false);
}
@@ -820,7 +840,7 @@ int getPrevGeometry(int geom) {
// Returns the type of the Geometry.
int getGeometryType(int geom) {
- return m_geometry_index_list.getField(geom, 2);
+ return m_geometry_index_list.getField(geom, 2) & 0x7FFFFFFF;
}
// Sets value to the given user index on a geometry.
@@ -897,10 +917,13 @@ int getPathCount(int geom) {
// 0 if no segments have been removed.
// When b_remove_last_vertices and the result path is < 3 for polygon or < 2
// for polyline, it'll be removed.
- int filterClosePoints(double tolerance, boolean b_remove_last_vertices) {
+ int filterClosePoints(double tolerance, boolean b_remove_last_vertices, boolean only_polygons) {
int res = 0;
for (int geometry = getFirstGeometry(); geometry != -1; geometry = getNextGeometry(geometry)) {
- if (!Geometry.isMultiPath(getGeometryType(geometry)))
+ int gt = getGeometryType(geometry);
+ if (!Geometry.isMultiPath(gt))
+ continue;
+ if (only_polygons && gt != GeometryType.Polygon)
continue;
boolean b_polygon = getGeometryType(geometry) == Geometry.GeometryType.Polygon;
@@ -1075,7 +1098,7 @@ int splitSegment(int origin_vertex, double[] split_scalars, int split_count) {
int actual_splits = 0;
int next_vertex = getNextVertex(origin_vertex);
if (next_vertex == -1)
- throw new IllegalArgumentException("internal error");
+ throw GeometryException.GeometryInternalError();
int vindex = getVertexIndex(origin_vertex);
int vindex_next = getVertexIndex(next_vertex);
@@ -1338,14 +1361,18 @@ void setWeight(int vertex, double weight) {
}
int vindex = getVertexIndex(vertex);
+ if (vindex >= m_weights.size()) {
+ m_weights.resize(vindex + 1, 1.0);
+ }
+
m_weights.write(vindex, weight);
}
double getWeight(int vertex) {
- if (m_weights == null)
- return 1.0;
-
int vindex = getVertexIndex(vertex);
+ if (m_weights == null || vindex >= m_weights.size())
+ return 1.0;
+
return m_weights.read(vindex);
}
@@ -1445,7 +1472,7 @@ int insertPath(int geometry, int before_path) {
if (before_path != -1) {
if (geometry != getGeometryFromPath(before_path))
- throw new IllegalArgumentException("internal error");
+ throw GeometryException.GeometryInternalError();
prev = getPrevPath(before_path);
} else
@@ -1468,6 +1495,45 @@ int insertPath(int geometry, int before_path) {
setGeometryPathCount_(geometry, getPathCount(geometry) + 1);
return newpath;
}
+
+ int insertClosedPath_(int geometry, int before_path, int first_vertex, int checked_vertex, boolean[] contains_checked_vertex)
+ {
+ int path = insertPath(geometry, -1);
+ int path_size = 0;
+ int vertex = first_vertex;
+ boolean contains = false;
+
+ while(true)
+ {
+ if (vertex == checked_vertex)
+ contains = true;
+
+ setPathToVertex_(vertex, path);
+ path_size++;
+ int next = getNextVertex(vertex);
+ assert(getNextVertex(getPrevVertex(vertex)) == vertex);
+ if (next == first_vertex)
+ break;
+
+ vertex = next;
+ }
+
+ setClosedPath(path, true);
+ setPathSize_(path, path_size);
+ if (contains)
+ first_vertex = checked_vertex;
+
+ setFirstVertex_(path, first_vertex);
+ setLastVertex_(path, getPrevVertex(first_vertex));
+ setRingAreaValid_(path, false);
+
+ if (contains_checked_vertex != null) {
+ contains_checked_vertex[0] = contains;
+ }
+
+ return path;
+ }
+
// Removes a path, gets rid of all its vertices, and returns the next one
int removePath(int path) {
@@ -1566,7 +1632,7 @@ void closeAllPaths(int geometry) {
if (getGeometryType(geometry) == Geometry.GeometryType.Polygon)
return;
if (!Geometry.isLinear(getGeometryType(geometry)))
- throw new IllegalArgumentException("internal error");
+ throw GeometryException.GeometryInternalError();
for (int path = getFirstPath(geometry); path != -1; path = getNextPath(path)) {
setClosedPath(path, true);
@@ -1799,6 +1865,14 @@ int getPrevVertex(int currentVertex) {
return m_vertex_index_list.getField(currentVertex, 1);
}
+ int getPrevVertex(int currentVertex, int dir) {
+ return dir > 0 ? m_vertex_index_list.getField(currentVertex, 1) : m_vertex_index_list.getField(currentVertex, 2);
+ }
+
+ int getNextVertex(int currentVertex, int dir) {
+ return dir > 0 ? m_vertex_index_list.getField(currentVertex, 2) : m_vertex_index_list.getField(currentVertex, 1);
+ }
+
// Returns a path the vertex belongs to.
int getPathFromVertex(int vertex) {
return m_vertex_index_list.getField(vertex, 3);
@@ -2000,8 +2074,7 @@ void interpolateAttributesForClosedPath_(int semantics, int path,
}
cumulative_length += segment_length;
double t = cumulative_length / sub_length;
- prev_interpolated_attribute = (1.0 - t) * from_attribute + t
- * to_attribute;
+ prev_interpolated_attribute = MathUtils.lerp(from_attribute, to_attribute, t);
}
return;
@@ -2231,4 +2304,52 @@ void sortVerticesSimpleByX_(AttributeStreamOfInt32 points, int begin_,
// The estimated size can be very slightly less than the actual size.
// int estimate_memory_size() const;
+ boolean hasPointFeatures()
+ {
+ for (int geometry = getFirstGeometry(); geometry != -1; geometry = getNextGeometry(geometry))
+ {
+ if (!Geometry.isMultiPath(getGeometryType(geometry)))
+ return true;
+ }
+ return false;
+ }
+
+ void swapGeometry(int geom1, int geom2)
+ {
+ int first_path1 = getFirstPath(geom1);
+ int first_path2 = getFirstPath(geom2);
+ int last_path1 = getLastPath(geom1);
+ int last_path2 = getLastPath(geom2);
+
+ for (int path = getFirstPath(geom1); path != -1; path = getNextPath(path))
+ {
+ setPathGeometry_(path, geom2);
+ }
+
+ for (int path = getFirstPath(geom2); path != -1; path = getNextPath(path))
+ {
+ setPathGeometry_(path, geom1);
+ }
+
+ setFirstPath_(geom1, first_path2);
+ setFirstPath_(geom2, first_path1);
+ setLastPath_(geom1, last_path2);
+ setLastPath_(geom2, last_path1);
+
+ int vc1 = getPointCount(geom1);
+ int pc1 = getPathCount(geom1);
+ int vc2 = getPointCount(geom2);
+ int pc2 = getPathCount(geom2);
+
+ setGeometryVertexCount_(geom1, vc2);
+ setGeometryVertexCount_(geom2, vc1);
+ setGeometryPathCount_(geom1, pc2);
+ setGeometryPathCount_(geom2, pc1);
+
+ int gt1 = m_geometry_index_list.getField(geom1, 2);
+ int gt2 = m_geometry_index_list.getField(geom2, 2);
+ m_geometry_index_list.setField(geom1, 2, gt2);
+ m_geometry_index_list.setField(geom2, 2, gt1);
+ }
+
}
diff --git a/src/main/java/com/esri/core/geometry/EnvSrlzr.java b/src/main/java/com/esri/core/geometry/EnvSrlzr.java
new file mode 100644
index 00000000..a6cea40a
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/EnvSrlzr.java
@@ -0,0 +1,95 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+//This is a writeReplace class for Envelope
+public class EnvSrlzr implements Serializable {
+ private static final long serialVersionUID = 1L;
+ double[] attribs;
+ int descriptionBitMask;
+
+ public Object readResolve() throws ObjectStreamException {
+ Envelope env = null;
+ if (descriptionBitMask == -1)
+ return null;
+
+ try {
+ VertexDescription vd = VertexDescriptionDesignerImpl
+ .getVertexDescription(descriptionBitMask);
+ env = new Envelope(vd);
+ if (attribs != null) {
+ env.setCoords(attribs[0], attribs[1], attribs[2], attribs[3]);
+ int index = 4;
+ for (int i = 1, n = vd.getAttributeCount(); i < n; i++) {
+ int semantics = vd.getSemantics(i);
+ int comps = VertexDescription.getComponentCount(semantics);
+ for (int ord = 0; ord < comps; ord++) {
+ env.setInterval(semantics, ord, attribs[index++], attribs[index++]);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot read geometry from stream");
+ }
+
+ return env;
+ }
+
+ public void setGeometryByValue(Envelope env) throws ObjectStreamException {
+ try {
+ attribs = null;
+ if (env == null) {
+ descriptionBitMask = -1;
+ }
+
+ VertexDescription vd = env.getDescription();
+ descriptionBitMask = vd.m_semanticsBitArray;
+ if (env.isEmpty()) {
+ return;
+ }
+
+ attribs = new double[vd.getTotalComponentCount() * 2];
+ attribs[0] = env.getXMin();
+ attribs[1] = env.getYMin();
+ attribs[2] = env.getXMax();
+ attribs[3] = env.getYMax();
+ int index = 4;
+ for (int i = 1, n = vd.getAttributeCount(); i < n; i++) {
+ int semantics = vd.getSemantics(i);
+ int comps = VertexDescription.getComponentCount(semantics);
+ for (int ord = 0; ord < comps; ord++) {
+ Envelope1D e = env.queryInterval(semantics, ord);
+ attribs[index++] = e.vmin;
+ attribs[index++] = e.vmax;
+ }
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot serialize this geometry");
+ }
+ }
+}
diff --git a/src/com/esri/core/geometry/Envelope.java b/src/main/java/com/esri/core/geometry/Envelope.java
similarity index 83%
rename from src/com/esri/core/geometry/Envelope.java
rename to src/main/java/com/esri/core/geometry/Envelope.java
index e51c4ee8..c254df1c 100644
--- a/src/com/esri/core/geometry/Envelope.java
+++ b/src/main/java/com/esri/core/geometry/Envelope.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,19 +25,22 @@
package com.esri.core.geometry;
+import com.esri.core.geometry.VertexDescription.Semantics;
+
import java.io.Serializable;
-import com.esri.core.geometry.VertexDescription.Semantics;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_ENVELOPE;
/**
* An envelope is an axis-aligned rectangle.
*/
-public final class Envelope extends Geometry implements Serializable {
- private static final long serialVersionUID = 2L;
+public class Envelope extends Geometry implements Serializable {
+ //We are using writeReplace instead.
+ //private static final long serialVersionUID = 2L;
Envelope2D m_envelope = new Envelope2D();
- double[] m_attributes;// use doubles to store everything (int64 are bitcast)
+ double[] m_attributes;// use doubles to store everything
/**
* Creates an envelope by defining its center, width, and height.
@@ -58,25 +61,29 @@ public Envelope(Point center, double width, double height) {
_setFromPoint(center, width, height);
}
- Envelope(Envelope2D env2D) {
+ public Envelope(Envelope2D env2D) {
m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
m_envelope.setCoords(env2D);
m_envelope.normalize();
}
- Envelope(VertexDescription vd) {
+ public Envelope(VertexDescription vd) {
if (vd == null)
throw new IllegalArgumentException();
+
m_description = vd;
m_envelope.setEmpty();
+ _ensureAttributes();
}
- Envelope(VertexDescription vd, Envelope2D env2D) {
+ public Envelope(VertexDescription vd, Envelope2D env2D) {
if (vd == null)
throw new IllegalArgumentException();
+
m_description = vd;
m_envelope.setCoords(env2D);
m_envelope.normalize();
+ _ensureAttributes();
}
/**
@@ -136,6 +143,14 @@ public void setCoords(double xmin, double ymin, double xmax, double ymax) {
m_envelope.setCoords(xmin, ymin, xmax, ymax);
}
+ /**
+ * Sets the envelope from the array of points. The result envelope is a
+ * bounding box of all the points in the array. If the array has zero
+ * length, the envelope will be empty.
+ *
+ * @param points
+ * The point array.
+ */
void setCoords(Point[] points) {
_touch();
setEmpty();
@@ -207,16 +222,16 @@ public double getCenterY() {
return m_envelope.getCenterY();
}
- /**
+ /**
* The x and y-coordinates of the center of the envelope.
*
* @return A point whose x and y-coordinates are that of the center of the envelope.
*/
- Point2D getCenterXY() {
+ public Point2D getCenterXY() {
return m_envelope.getCenter();
}
- void getCenter(Point point_out) {
+ public void getCenter(Point point_out) {
point_out.assignVertexDescription(m_description);
if (isEmpty()) {
point_out.setEmpty();
@@ -236,7 +251,7 @@ void getCenter(Point point_out) {
point_out.setXY(m_envelope.getCenter());
}
- void merge(Point2D pt) {
+ public void merge(Point2D pt) {
_touch();
m_envelope.merge(pt);
}
@@ -320,8 +335,8 @@ void _setFromPoint(Point centerPoint, double width, double height) {
}
void _setFromPoint(Point centerPoint) {
- m_envelope.setCoords(centerPoint.m_attributes[0],
- centerPoint.m_attributes[1]);
+ mergeVertexDescription(centerPoint.getDescription());
+ m_envelope.setCoords(centerPoint.getX(), centerPoint.getY());
VertexDescription pointVD = centerPoint.m_description;
for (int iattrib = 1, nattrib = pointVD.getAttributeCount(); iattrib < nattrib; iattrib++) {
int semantics = pointVD._getSemanticsImpl(iattrib);
@@ -333,7 +348,7 @@ void _setFromPoint(Point centerPoint) {
}
}
- void merge(Envelope2D other) {
+ public void merge(Envelope2D other) {
_touch();
m_envelope.merge(other);
}
@@ -402,9 +417,13 @@ public void copyTo(Geometry dst) {
dst._touch();
envDst.m_description = m_description;
envDst.m_envelope.setCoords(m_envelope);
- envDst._resizeAttributes(m_description._getTotalComponents() - 2);
- _attributeCopy(m_attributes, 0, envDst.m_attributes, 0,
- (m_description._getTotalComponents() - 2) * 2);
+ envDst.m_attributes = null;
+ if (m_attributes != null)
+ {
+ envDst._ensureAttributes();
+ System.arraycopy(m_attributes, 0, envDst.m_attributes, 0,
+ (m_description.getTotalComponentCount() - 2) * 2);
+ }
}
@Override
@@ -432,6 +451,12 @@ public int getDimension() {
return 2;
}
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_ENVELOPE + m_envelope.estimateMemorySize() + estimateMemorySize(m_attributes);
+ }
+
@Override
public void queryEnvelope(Envelope env) {
copyTo(env);
@@ -481,7 +506,7 @@ public void setInterval(int semantics, int ordinate, Envelope1D env) {
}
}
- void queryCoordinates(Point2D[] dst) {
+ public void queryCoordinates(Point2D[] dst) {
if (dst == null || dst.length < 4 || m_envelope.isEmpty())
throw new IllegalArgumentException();
@@ -561,7 +586,7 @@ public void queryCornerByVal(int index, Point ptDst) {
}
}
- void queryCorner(int index, Point2D ptDst) {
+ public void queryCorner(int index, Point2D ptDst) {
Point2D p = m_envelope.queryCorner(index);
ptDst.setCoords(p.x, p.y);
}
@@ -614,6 +639,8 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
else
m_envelope.xmin = value;
}
+
+ return;
}
int ncomps = VertexDescription.getComponentCount(semantics);
@@ -627,83 +654,66 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
+ ordinate] = value;
}
- void _resizeAttributes(int newSize) {// copied from
- // Segment::_ResizeAttributes
+ void _ensureAttributes() {
_touch();
- if (m_attributes == null) {
- m_attributes = new double[newSize * 2];
- } else if (m_attributes.length < newSize * 2) {
- double[] newBuffer = new double[newSize * 2];
- System.arraycopy(m_attributes, 0, newBuffer, 0, m_attributes.length);
- m_attributes = newBuffer;
- }
- }
-
- @Override
- void _beforeDropAttributeImpl(int semantics) {// copied from
- // Segment::_BeforeDropAttributeImpl
- if (m_envelope.isEmpty())
- return;
-
- // _ASSERT(semantics != enum_value2(VertexDescription, Semantics,
- // POSITION));
- int attributeIndex = m_description.getAttributeIndex(semantics);
- int offset = m_description._getPointAttributeOffset(attributeIndex) - 2;
- int comps = VertexDescription.getComponentCount(semantics);
- int totalCompsOld = m_description._getTotalComponents() - 2;
- if (totalCompsOld > comps) {
- int offset0 = _getEndPointOffset(0);
- for (int i = offset + comps; i < totalCompsOld * 2; i++)
- m_attributes[offset0 + i - comps] = m_attributes[offset0 + i];
-
- int offset1 = _getEndPointOffset(1) - comps; // -comp is for deleted
- // attribute of
- // start vertex
- for (int i = offset + comps; i < totalCompsOld; i++)
- m_attributes[offset1 + i - comps] = m_attributes[offset1 + i];
+ if (m_attributes == null && m_description.getTotalComponentCount() > 2) {
+ int halfLength = m_description.getTotalComponentCount() - 2;
+ m_attributes = new double[halfLength * 2];
+ int offset0 = _getEndPointOffset(m_description, 0);
+ int offset1 = _getEndPointOffset(m_description, 1);
+ System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset0, halfLength);
+ System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset1, halfLength);
}
}
@Override
- void _afterAddAttributeImpl(int semantics) {// copied from
- // Segment::_AfterAddAttributeImpl
- int attributeIndex = m_description.getAttributeIndex(semantics);
- int offset = m_description._getPointAttributeOffset(attributeIndex) - 2;
- int comps = VertexDescription.getComponentCount(semantics);
- int totalComps = m_description._getTotalComponents() - 2;
- _resizeAttributes(totalComps);
- int totalCompsOld = totalComps - comps; // the total number of
- // components before resize.
-
- int offset0 = _getEndPointOffset(0);
- int offset1 = _getEndPointOffset(1);
- int offset1old = offset1 - comps;
- for (int i = totalCompsOld - 1; i >= 0; i--) {// correct the position of
- // the End attributes
- m_attributes[offset1 + i] = m_attributes[offset1old + i];
- }
-
- // move attributes for start end end points that go after the insertion
- // point
- for (int i = totalComps - 1; i >= offset + comps; i--) {
- m_attributes[offset0 + i] = m_attributes[offset0 + i - comps];
- m_attributes[offset1 + i] = m_attributes[offset1 + i - comps];
+ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
+ if (newDescription.getTotalComponentCount() > 2) {
+ int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);
+
+ double[] newAttributes = new double[(newDescription.getTotalComponentCount() - 2) * 2];
+
+ int old_offset0 = _getEndPointOffset(m_description, 0);
+ int old_offset1 = _getEndPointOffset(m_description, 1);
+
+ int new_offset0 = _getEndPointOffset(newDescription, 0);
+ int new_offset1 = _getEndPointOffset(newDescription, 1);
+
+ int j = 0;
+ for (int i = 1, n = newDescription.getAttributeCount(); i < n; i++) {
+ int semantics = newDescription.getSemantics(i);
+ int nords = VertexDescription.getComponentCount(semantics);
+ if (mapping[i] == -1)
+ {
+ double d = VertexDescription.getDefaultValue(semantics);
+ for (int ord = 0; ord < nords; ord++)
+ {
+ newAttributes[new_offset0 + j] = d;
+ newAttributes[new_offset1 + j] = d;
+ j++;
+ }
+ }
+ else {
+ int m = mapping[i];
+ int offset = m_description._getPointAttributeOffset(m) - 2;
+ for (int ord = 0; ord < nords; ord++)
+ {
+ newAttributes[new_offset0 + j] = m_attributes[old_offset0 + offset];
+ newAttributes[new_offset1 + j] = m_attributes[old_offset1 + offset];
+ j++;
+ offset++;
+ }
+ }
+
+ }
+
+ m_attributes = newAttributes;
}
-
- // initialize added attribute to the default value.
- double dv = VertexDescription.getDefaultValue(semantics);
- for (int i = 0; i < comps; i++) {
- m_attributes[offset0 + offset + i] = dv;
- m_attributes[offset1 + offset + i] = dv;
+ else {
+ m_attributes = null;
}
- }
-
- static void _attributeCopy(double[] src, int srcStart, double[] dst,
- int dstStart, int count) {
- // FIXME performance!!!!
- // System.arraycopy(src, srcStart, dst, dstStart, count);
- for (int i = 0; i < count; i++)
- dst[dstStart + i] = src[i + srcStart];
+
+ m_description = newDescription;
}
double _getAttributeAsDbl(int endPoint, int semantics, int ordinate) {
@@ -711,8 +721,6 @@ static void _attributeCopy(double[] src, int srcStart, double[] dst,
throw new GeometryException(
"This operation was performed on an Empty Geometry.");
- // _ASSERT(endPoint == 0 || endPoint == 1);
-
if (semantics == Semantics.POSITION) {
if (endPoint != 0) {
return ordinate != 0 ? m_envelope.ymax : m_envelope.xmax;
@@ -727,10 +735,7 @@ static void _attributeCopy(double[] src, int srcStart, double[] dst,
int attributeIndex = m_description.getAttributeIndex(semantics);
if (attributeIndex >= 0) {
- if (null != m_attributes)
- _resizeAttributes(m_description._getTotalComponents() - 2);
-
- return m_attributes[_getEndPointOffset(endPoint)
+ return m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex)
- 2 + ordinate];
} else
@@ -754,6 +759,8 @@ void _setAttributeAsDbl(int endPoint, int semantics, int ordinate,
else
m_envelope.xmin = value;
}
+
+ return;
}
int ncomps = VertexDescription.getComponentCount(semantics);
@@ -761,16 +768,11 @@ void _setAttributeAsDbl(int endPoint, int semantics, int ordinate,
throw new IndexOutOfBoundsException();
if (!hasAttribute(semantics)) {
- if (VertexDescription.isDefaultValue(semantics, value))
- return;
addAttribute(semantics);
}
int attributeIndex = m_description.getAttributeIndex(semantics);
- if (null == m_attributes)
- _resizeAttributes(m_description._getTotalComponents() - 2);
-
- m_attributes[_getEndPointOffset(endPoint)
+ m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex) - 2
+ ordinate] = value;
}
@@ -779,11 +781,11 @@ int _getAttributeAsInt(int endPoint, int semantics, int ordinate) {
return (int) _getAttributeAsDbl(endPoint, semantics, ordinate);
}
- int _getEndPointOffset(int endPoint) {
- return endPoint * (m_description._getTotalComponents() - 2);
+ static int _getEndPointOffset(VertexDescription vd, int endPoint) {
+ return endPoint * (vd.getTotalComponentCount() - 2);
}
- boolean isIntersecting(Envelope2D other) {
+ public boolean isIntersecting(Envelope2D other) {
return m_envelope.isIntersecting(other);
}
@@ -862,7 +864,7 @@ public void normalize() {// TODO: attributes
*
* @return The center point of the envelope.
*/
- Point2D getCenter2D() {
+ public Point2D getCenter2D() {
return m_envelope.getCenter();
}
@@ -912,7 +914,7 @@ public void centerAt(Point c) {
* @return Returns the lower left corner point.
*/
public Point getLowerLeft() {
- return m_envelope.getLowerLeft();
+ return new Point(m_envelope.getLowerLeft());
}
/**
@@ -921,7 +923,7 @@ public Point getLowerLeft() {
* @return Returns the upper right corner point.
*/
public Point getUpperRight() {
- return m_envelope.getUpperRight();
+ return new Point(m_envelope.getUpperRight());
}
/**
@@ -930,7 +932,7 @@ public Point getUpperRight() {
* @return Returns the lower right corner point.
*/
public Point getLowerRight() {
- return m_envelope.getLowerRight();
+ return new Point(m_envelope.getLowerRight());
}
/**
@@ -939,7 +941,7 @@ public Point getLowerRight() {
* @return Returns the upper left corner point.
*/
public Point getUpperLeft() {
- return m_envelope.getUpperLeft();
+ return new Point(m_envelope.getUpperLeft());
}
/**
@@ -992,8 +994,8 @@ public boolean equals(Object _other) {
if (!this.m_envelope.equals(other.m_envelope))
return false;
- for (int i = 0, n = (m_description._getTotalComponents() - 2) * 2; i < n; i++)
- if (m_attributes[i] != other.m_attributes[i])
+ for (int i = 0, n = (m_description.getTotalComponentCount() - 2) * 2; i < n; i++)
+ if (!NumberUtils.isEqualNonIEEE(m_attributes[i], other.m_attributes[i]))
return false;
return true;
@@ -1008,8 +1010,8 @@ public boolean equals(Object _other) {
public int hashCode() {
int hashCode = m_description.hashCode();
hashCode = NumberUtils.hash(hashCode, m_envelope.hashCode());
- if (!isEmpty() && m_attributes != null) {
- for (int i = 0, n = (m_description._getTotalComponents() - 2) * 2; i < n; i++) {
+ if (!isEmpty()) {
+ for (int i = 0, n = (m_description.getTotalComponentCount() - 2) * 2; i < n; i++) {
hashCode = NumberUtils.hash(hashCode, m_attributes[i]);
}
}
@@ -1095,4 +1097,39 @@ public void setYMax(double y) {
_touch();
m_envelope.ymax = y;
}
+
+ @Override
+ public Geometry getBoundary() {
+ return Boundary.calculate(this, null);
+ }
+
+ @Override
+ public void replaceNaNs(int semantics, double value) {
+ addAttribute(semantics);
+ if (isEmpty())
+ return;
+
+ int ncomps = VertexDescription.getComponentCount(semantics);
+ for (int i = 0; i < ncomps; i++) {
+ Envelope1D interval = queryInterval(semantics, i);
+ if (interval.isEmpty()) {
+ interval.vmin = value;
+ interval.vmax = value;
+ setInterval(semantics, i, interval);
+ }
+ }
+ }
+
+ /**
+ * The output of this method can be only used for debugging. It is subject to change without notice.
+ */
+ @Override
+ public String toString() {
+ if (isEmpty())
+ return "Envelope: []";
+
+ String s = "Envelope: [" + m_envelope.xmin + ", " + m_envelope.ymin + ", " + m_envelope.xmax + ", " + m_envelope.ymax +"]";
+ return s;
+ }
+
}
diff --git a/src/com/esri/core/geometry/Envelope1D.java b/src/main/java/com/esri/core/geometry/Envelope1D.java
similarity index 75%
rename from src/com/esri/core/geometry/Envelope1D.java
rename to src/main/java/com/esri/core/geometry/Envelope1D.java
index e0d19408..e000ef0a 100644
--- a/src/com/esri/core/geometry/Envelope1D.java
+++ b/src/main/java/com/esri/core/geometry/Envelope1D.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,10 +25,13 @@
package com.esri.core.geometry;
+import java.io.Serializable;
+
/**
* A 1-dimensional interval.
*/
-public final class Envelope1D {
+public final class Envelope1D implements Serializable {
+ private static final long serialVersionUID = 1L;
public double vmin;
@@ -42,13 +45,21 @@ public Envelope1D(double _vmin, double _vmax) {
setCoords(_vmin, _vmax);
}
+ public Envelope1D(Envelope1D other) {
+ setCoords(other);
+ }
+
public void setCoords(double _vmin, double _vmax) {
vmin = _vmin;
vmax = _vmax;
normalize();
}
- void normalize() {
+ public void setCoords(Envelope1D other) {
+ setCoords(other.vmin, other.vmax);
+ }
+
+ public void normalize() {
if (NumberUtils.isNaN(vmin))
return;
if (vmin > vmax) {
@@ -64,10 +75,11 @@ void normalize() {
public void setEmpty() {
vmin = NumberUtils.NaN();
+ vmax = NumberUtils.NaN();
}
public boolean isEmpty() {
- return NumberUtils.isNaN(vmin);
+ return NumberUtils.isNaN(vmin) || NumberUtils.isNaN(vmax);
}
public void setInfinite() {
@@ -121,8 +133,10 @@ public boolean contains(double v) {
/**
* Returns True if the envelope contains the other envelope (boundary
* inclusive). Note: Will return false if either envelope is empty.
+ * @param other The other envelope.
+ * @return Return true if this contains the other.
*/
- public boolean contains(/* const */Envelope1D other) /* const */
+ public boolean contains(Envelope1D other)
{
return other.vmin >= vmin && other.vmax <= vmax;
}
@@ -175,7 +189,7 @@ void setCoordsNoNaN_(double vmin_, double vmax_) {
normalizeNoNaN_();
}
- double snapClip(double v) /* const */
+ public double snapClip(double v) /* const */
{
return NumberUtils.snap(v, vmin, vmax);
}
@@ -189,4 +203,35 @@ public double getCenter() /* const */
{
return 0.5 * (vmin + vmax);
}
+
+ @Override
+ public boolean equals(Object _other)
+ {
+ if (_other == this)
+ return true;
+
+ if (!(_other instanceof Envelope1D))
+ return false;
+
+ Envelope1D other = (Envelope1D) _other;
+ if (isEmpty() && other.isEmpty())
+ return true;
+
+ if (vmin != other.vmin || vmax != other.vmax)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ if (isEmpty()) {
+ return NumberUtils.hash(NumberUtils.TheNaN);
+ }
+
+ int hash = NumberUtils.hash(vmin);
+ hash = NumberUtils.hash(hash, vmax);
+ return hash;
+ }
+
}
diff --git a/src/com/esri/core/geometry/Envelope2D.java b/src/main/java/com/esri/core/geometry/Envelope2D.java
similarity index 74%
rename from src/com/esri/core/geometry/Envelope2D.java
rename to src/main/java/com/esri/core/geometry/Envelope2D.java
index 2ea01b86..5c8bebf5 100644
--- a/src/com/esri/core/geometry/Envelope2D.java
+++ b/src/main/java/com/esri/core/geometry/Envelope2D.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,25 +24,32 @@
package com.esri.core.geometry;
+import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_ENVELOPE2D;
+
/**
* An axis parallel 2-dimensional rectangle.
*/
-public final class Envelope2D {
+public final class Envelope2D implements Serializable {
+ private static final long serialVersionUID = 1L;
- private final int XLESSXMIN = 1;
+ private final static int XLESSXMIN = 1;
// private final int XGREATERXMAX = 2;
- private final int YLESSYMIN = 4;
+ private final static int YLESSYMIN = 4;
// private final int YGREATERYMAX = 8;
- private final int XMASK = 3;
- private final int YMASK = 12;
+ private final static int XMASK = 3;
+ private final static int YMASK = 12;
- double xmin;
+ public double xmin;
- double ymin;
+ public double ymin;
- double xmax;
+ public double xmax;
- double ymax;
+ public double ymax;
public static Envelope2D construct(double _xmin, double _ymin,
double _xmax, double _ymax) {
@@ -54,6 +61,12 @@ public static Envelope2D construct(double _xmin, double _ymin,
return env;
}
+ public static Envelope2D construct(Envelope2D other) {
+ Envelope2D env = new Envelope2D();
+ env.setCoords(other);
+ return env;
+ }
+
public Envelope2D() {
setEmpty();
}
@@ -65,6 +78,15 @@ public Envelope2D(double _xmin, double _ymin, double _xmax, double _ymax) {
ymax = _ymax;
}
+ public Envelope2D(Envelope2D other) {
+ setCoords(other);
+ }
+
+ public int estimateMemorySize()
+ {
+ return SIZE_OF_ENVELOPE2D;
+ }
+
public void setCoords(double _x, double _y) {
xmin = _x;
ymin = _y;
@@ -109,6 +131,7 @@ public Envelope2D getInflated(double dx, double dy) {
/**
* Sets the envelope from the array of points. The envelope will be set to
* empty if the array is null.
+ * @param points The points to set the envelope from. No element in the array can be null.
*/
public void setFromPoints(Point2D[] points) {
if (points == null || points.length == 0) {
@@ -139,7 +162,7 @@ public void setInfinite() {
}
public boolean isEmpty() {
- return NumberUtils.isNaN(xmin);
+ return NumberUtils.isNaN(xmin) || NumberUtils.isNaN(ymin) || NumberUtils.isNaN(xmax) || NumberUtils.isNaN(ymax);
}
public void setCoords(Envelope1D xinterval, Envelope1D yinterval) {
@@ -176,6 +199,8 @@ else if (ymax < y)
/**
* Merges a point with this envelope without checking if the envelope is
* empty. Use with care.
+ * @param x The x coord of the point
+ * @param y the y coord in the point
*/
public void mergeNE(double x, double y) {
if (xmin > x)
@@ -235,14 +260,14 @@ public void zoom(double factorX, double factorY) {
}
/**
- * Checks if this envelope intersects the other.
+ * Checks if this envelope intersects the other.
+ * @param other The other envelope.
* @return True if this envelope intersects the other.
*/
public boolean isIntersecting(Envelope2D other) {
- return !isEmpty()
- && !other.isEmpty()
- && ((xmin <= other.xmin) ? xmax >= other.xmin
- : other.xmax >= xmin)
+ // No need to check if empty, this will work for empty envelopes too
+ // (IEEE math)
+ return ((xmin <= other.xmin) ? xmax >= other.xmin : other.xmax >= xmin)
&& // check that x projections overlap
((ymin <= other.ymin) ? ymax >= other.ymin : other.ymax >= ymin); // check
// that
@@ -252,7 +277,8 @@ public boolean isIntersecting(Envelope2D other) {
}
/**
- * Checks if this envelope intersects the other assuming neither one is empty.
+ * Checks if this envelope intersects the other assuming neither one is empty.
+ * @param other The other envelope.
* @return True if this envelope intersects the other. Assumes this and
* other envelopes are not empty.
*/
@@ -267,12 +293,38 @@ public boolean isIntersectingNE(Envelope2D other) {
}
/**
- * Checks if this envelope intersects the other.
- * @return True if this envelope intersects the other.
+ * Checks if this envelope intersects the other.
+ * @param xmin_
+ * @param ymin_
+ * @param xmax_
+ * @param ymax_
+ * @return True if this envelope intersects the other.
+ */
+ public boolean isIntersecting(double xmin_, double ymin_, double xmax_, double ymax_) {
+ // No need to check if empty, this will work for empty geoms too (IEEE
+ // math)
+ return ((xmin <= xmin_) ? xmax >= xmin_ : xmax_ >= xmin) && // check
+ // that x
+ // projections
+ // overlap
+ ((ymin <= ymin_) ? ymax >= ymin_ : ymax_ >= ymin); // check that
+ // y
+ // projections
+ // overlap
+ }
+
+ /**
+ * Intersects this envelope with the other and stores result in this
+ * envelope.
+ * @param other The other envelope.
+ * @return True if this envelope intersects the other, otherwise sets this
+ * envelope to empty state and returns False.
*/
public boolean intersect(Envelope2D other) {
- if (isEmpty() || other.isEmpty())
+ if (isEmpty() || other.isEmpty()) {
+ setEmpty();
return false;
+ }
if (other.xmin > xmin)
xmin = other.xmin;
@@ -295,15 +347,20 @@ public boolean intersect(Envelope2D other) {
}
/**
- * Queries a corner of the envelope.
- *
- * @param index Indicates a corner of the envelope.
- * 0 => lower left or (xmin, ymin)
- *
1 => upper left or (xmin, ymax)
- *
2 => upper right or (xmax, ymax)
- *
3 => lower right or (xmax, ymin)
- * @return Point at a corner of the envelope.
- *
+ * Queries a corner of the envelope.
+ *
+ * @param index
+ * Indicates a corner of the envelope.
+ *
+ * 0 means lower left or (xmin, ymin)
+ *
+ * 1 means upper left or (xmin, ymax)
+ *
+ * 2 means upper right or (xmax, ymax)
+ *
+ * 3 means lower right or (xmax, ymin)
+ * @return Point at a corner of the envelope.
+ *
*/
public Point2D queryCorner(int index) {
switch (index) {
@@ -324,28 +381,60 @@ public Point2D queryCorner(int index) {
/**
* Queries corners into a given array. The array length must be at least
* 4. Starts from the lower left corner and goes clockwise.
+ * @param corners The array of four points.
*/
public void queryCorners(Point2D[] corners) {
if ((corners == null) || (corners.length < 4))
throw new IllegalArgumentException();
- corners[0] = new Point2D(xmin, ymin);
- corners[1] = new Point2D(xmin, ymax);
- corners[2] = new Point2D(xmax, ymax);
- corners[3] = new Point2D(xmax, ymin);
+ if (corners[0] != null)
+ corners[0].setCoords(xmin, ymin);
+ else
+ corners[0] = new Point2D(xmin, ymin);
+
+ if (corners[1] != null)
+ corners[1].setCoords(xmin, ymax);
+ else
+ corners[1] = new Point2D(xmin, ymax);
+
+ if (corners[2] != null)
+ corners[2].setCoords(xmax, ymax);
+ else
+ corners[2] = new Point2D(xmax, ymax);
+
+ if (corners[3] != null)
+ corners[3].setCoords(xmax, ymin);
+ else
+ corners[3] = new Point2D(xmax, ymin);
}
/**
* Queries corners into a given array in reversed order. The array length
* must be at least 4. Starts from the lower left corner and goes
* counterclockwise.
+ * @param corners The array of four points.
*/
public void queryCornersReversed(Point2D[] corners) {
if (corners == null || ((corners != null) && (corners.length < 4)))
throw new IllegalArgumentException();
- corners[0] = new Point2D(xmin, ymin);
- corners[1] = new Point2D(xmax, ymin);
- corners[2] = new Point2D(xmax, ymax);
- corners[3] = new Point2D(xmin, ymax);
+ if (corners[0] != null)
+ corners[0].setCoords(xmin, ymin);
+ else
+ corners[0] = new Point2D(xmin, ymin);
+
+ if (corners[1] != null)
+ corners[1].setCoords(xmax, ymin);
+ else
+ corners[1] = new Point2D(xmax, ymin);
+
+ if (corners[2] != null)
+ corners[2].setCoords(xmax, ymax);
+ else
+ corners[2] = new Point2D(xmax, ymax);
+
+ if (corners[3] != null)
+ corners[3].setCoords(xmin, ymax);
+ else
+ corners[3] = new Point2D(xmin, ymax);
}
public double getArea() {
@@ -424,6 +513,8 @@ public double getHeight() {
/**
* Moves the Envelope by given distance.
+ * @param dx
+ * @param dy
*/
public void move(double dx, double dy) {
if (isEmpty())
@@ -482,6 +573,7 @@ public void queryUpperRight(Point2D pt) {
/**
* Returns True if this envelope is valid (empty, or has xmin less or equal
* to xmax, or ymin less or equal to ymax).
+ * @return True if the envelope is valid.
*/
public boolean isValid() {
return isEmpty() || (xmin <= xmax && ymin <= ymax);
@@ -512,20 +604,20 @@ public void centerAt(Point c) {
ymax = c.getY() + cy;
}
- public Point getLowerLeft() {
- return new Point(xmin, ymin);
+ public Point2D getLowerLeft() {
+ return new Point2D(xmin, ymin);
}
- public Point getUpperLeft() {
- return new Point(xmin, ymax);
+ public Point2D getUpperLeft() {
+ return new Point2D(xmin, ymax);
}
- public Point getLowerRight() {
- return new Point(xmax, ymin);
+ public Point2D getLowerRight() {
+ return new Point2D(xmax, ymin);
}
- public Point getUpperRight() {
- return new Point(xmax, ymax);
+ public Point2D getUpperRight() {
+ return new Point2D(xmax, ymax);
}
public boolean contains(Point p) {
@@ -537,12 +629,16 @@ public boolean contains(Point2D p) {
}
public boolean contains(double x, double y) {
- return (!isEmpty() && (x >= xmin && x <= xmax && y >= ymin && y <= ymax));
+ // Note: This will return False, if envelope is empty, thus no need to
+ // call is_empty().
+ return x >= xmin && x <= xmax && y >= ymin && y <= ymax;
}
/**
* Returns True if the envelope contains the other envelope (boundary
* inclusive).
+ * @param other The other envelope.
+ * @return True if this contains the other.
*/
public boolean contains(Envelope2D other) {// Note: Will return False, if
// either envelope is empty.
@@ -552,8 +648,11 @@ public boolean contains(Envelope2D other) {// Note: Will return False, if
/**
* Returns True if the envelope contains the point (boundary exclusive).
- */
- boolean containsExclusive(double x, double y) {
+ * @param x
+ * @param y
+ * @return True if this contains the point.
+ * */
+ public boolean containsExclusive(double x, double y) {
// Note: This will return False, if envelope is empty, thus no need to
// call is_empty().
return x > xmin && x < xmax && y > ymin && y < ymax;
@@ -562,13 +661,15 @@ boolean containsExclusive(double x, double y) {
/**
* Returns True if the envelope contains the point (boundary exclusive).
*/
- boolean containsExclusive(Point2D pt) {
- return contains(pt.x, pt.y);
+ public boolean containsExclusive(Point2D pt) {
+ return containsExclusive(pt.x, pt.y);
}
/**
* Returns True if the envelope contains the other envelope (boundary
* exclusive).
+ * @param other The other envelope
+ * @return True if this contains the other, boundary exclusive.
*/
boolean containsExclusive(Envelope2D other) {
// Note: This will return False, if either envelope is empty, thus no
@@ -598,23 +699,14 @@ public boolean equals(Object _other) {
@Override
public int hashCode() {
-
- long bits = Double.doubleToLongBits(xmin);
- int hc = (int) (bits ^ (bits >>> 32));
-
- int hash = NumberUtils.hash(hc);
-
- bits = Double.doubleToLongBits(xmax);
- hc = (int) (bits ^ (bits >>> 32));
- hash = NumberUtils.hash(hash, hc);
-
- bits = Double.doubleToLongBits(ymin);
- hc = (int) (bits ^ (bits >>> 32));
- hash = NumberUtils.hash(hash, hc);
-
- bits = Double.doubleToLongBits(ymax);
- hc = (int) (bits ^ (bits >>> 32));
- hash = NumberUtils.hash(hash, hc);
+ if (isEmpty()) {
+ return NumberUtils.hash(NumberUtils.TheNaN);
+ }
+
+ int hash = NumberUtils.hash(xmin);
+ hash = NumberUtils.hash(hash, xmax);
+ hash = NumberUtils.hash(hash, ymin);
+ hash = NumberUtils.hash(hash, ymax);
return hash;
}
@@ -974,7 +1066,7 @@ boolean clipLineAuxiliary(double denominator, double numerator,
* Returns True, envelope is degenerate (Width or Height are less than
* tolerance). Note: this returns False for Empty envelope.
*/
- boolean isDegenerate(double tolerance) {
+ public boolean isDegenerate(double tolerance) {
return !isEmpty()
&& (getWidth() <= tolerance || getHeight() <= tolerance);
}
@@ -987,26 +1079,43 @@ Point2D _snapClip(Point2D pt)// clips the point if it is outside, then snaps
return new Point2D(x, y);
}
- boolean isPointOnBoundary(Point2D pt, double tolerance) {
+ public boolean isPointOnBoundary(Point2D pt, double tolerance) {
return Math.abs(pt.x - xmin) <= tolerance
|| Math.abs(pt.x - xmax) <= tolerance
|| Math.abs(pt.y - ymin) <= tolerance
|| Math.abs(pt.y - ymax) <= tolerance;
}
- double distance(/* const */Envelope2D other) /* const */
+ /**
+ * Calculates minimum distance from this envelope to the other.
+ * Returns 0 for empty envelopes.
+ * @param other The other envelope.
+ * @return Returns the distance
+ */
+ public double distance(Envelope2D other)
{
return Math.sqrt(sqrDistance(other));
}
- double distance(/* const */Point2D pt2D) /* const */
+ /**
+ * Calculates minimum distance from this envelope to the point.
+ * Returns 0 for empty envelopes.
+ * @param pt2D The other point.
+ * @return Returns the distance
+ */
+ public double distance(Point2D pt2D)
{
return Math.sqrt(sqrDistance(pt2D));
}
- double sqrDistance(/* const */Envelope2D other) /* const */
+ /**
+ * Calculates minimum squared distance from this envelope to the other.
+ * Returns 0 for empty envelopes.
+ * @param other The other envelope.
+ * @return Returns the squared distance
+ */
+ public double sqrDistance(Envelope2D other)
{
- // code from SG's windist
double dx = 0;
double dy = 0;
double nn;
@@ -1030,9 +1139,75 @@ boolean isPointOnBoundary(Point2D pt, double tolerance) {
return dx * dx + dy * dy;
}
- double sqrDistance(/* const */Point2D pt2D) /* const */
+ /**
+ * Calculates minimum squared distance from this envelope to the other.
+ * Returns 0 for empty envelopes.
+ * @param xmin_
+ * @param ymin_
+ * @param xmax_
+ * @param ymax_
+ * @return Returns the squared distance.
+ */
+ public double sqrDistance(double xmin_, double ymin_, double xmax_, double ymax_)
+ {
+ double dx = 0;
+ double dy = 0;
+ double nn;
+
+ nn = xmin - xmax_;
+ if (nn > dx)
+ dx = nn;
+
+ nn = ymin - ymax_;
+ if (nn > dy)
+ dy = nn;
+
+ nn = xmin_ - xmax;
+ if (nn > dx)
+ dx = nn;
+
+ nn = ymin_ - ymax;
+ if (nn > dy)
+ dy = nn;
+
+ return dx * dx + dy * dy;
+ }
+
+ /**
+ *Returns squared max distance between two bounding boxes. This is furthest distance between points on the two envelopes.
+ *
+ *@param other The bounding box to calculate the max distance two.
+ *@return Squared distance value.
+ */
+ public double sqrMaxDistance(Envelope2D other) {
+ if (isEmpty() || other.isEmpty())
+ return NumberUtils.TheNaN;
+
+ double dist = 0;
+ Point2D[] points = new Point2D[4];
+ queryCorners(points);
+ Point2D[] points_o = new Point2D[4];
+ other.queryCorners(points_o);
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ double d = Point2D.sqrDistance(points[i], points_o[j]);
+ if (d > dist) {
+ dist = d;
+ }
+ }
+ }
+
+ return dist;
+ }
+
+ /**
+ * Calculates minimum squared distance from this envelope to the point.
+ * Returns 0 for empty envelopes.
+ * @param pt2D The point.
+ * @return Returns the squared distance
+ */
+ public double sqrDistance(Point2D pt2D)
{
- // code from SG's windist
double dx = 0;
double dy = 0;
double nn;
@@ -1056,7 +1231,7 @@ boolean isPointOnBoundary(Point2D pt, double tolerance) {
return dx * dx + dy * dy;
}
- void queryIntervalX(Envelope1D env1D) /* const */
+ public void queryIntervalX(Envelope1D env1D)
{
if (isEmpty()) {
env1D.setEmpty();
@@ -1065,7 +1240,7 @@ void queryIntervalX(Envelope1D env1D) /* const */
}
}
- void queryIntervalY(Envelope1D env1D) /* const */
+ public void queryIntervalY(Envelope1D env1D)
{
if (isEmpty()) {
env1D.setEmpty();
@@ -1073,4 +1248,15 @@ void queryIntervalY(Envelope1D env1D) /* const */
env1D.setCoords(ymin, ymax);
}
}
+
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ }
+ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ }
+ private void readObjectNoData() throws ObjectStreamException {
+ setEmpty();
+ }
+
}
diff --git a/src/com/esri/core/geometry/Envelope2DIntersectorImpl.java b/src/main/java/com/esri/core/geometry/Envelope2DIntersectorImpl.java
similarity index 80%
rename from src/com/esri/core/geometry/Envelope2DIntersectorImpl.java
rename to src/main/java/com/esri/core/geometry/Envelope2DIntersectorImpl.java
index 874e90c5..35b83daa 100644
--- a/src/com/esri/core/geometry/Envelope2DIntersectorImpl.java
+++ b/src/main/java/com/esri/core/geometry/Envelope2DIntersectorImpl.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -39,17 +39,23 @@ void startConstruction() {
reset_();
m_b_add_red_red = true;
- if (m_envelopes_red == null)
+ if (m_envelopes_red == null) {
+ m_elements_red = new AttributeStreamOfInt32(0);
m_envelopes_red = new ArrayList(0);
- else
+ } else {
+ m_elements_red.resizePreserveCapacity(0);
m_envelopes_red.clear();
+ }
}
- void addEnvelope(Envelope2D envelope) {
+ void addEnvelope(int element, Envelope2D envelope) {
if (!m_b_add_red_red)
throw new GeometryException("invalid call");
- m_envelopes_red.add(envelope);
+ Envelope2D e = new Envelope2D();
+ e.setCoords(envelope);
+ m_elements_red.add(element);
+ m_envelopes_red.add(e);
}
void endConstruction() {
@@ -68,17 +74,23 @@ void startRedConstruction() {
reset_();
m_b_add_red = true;
- if (m_envelopes_red == null)
+ if (m_envelopes_red == null) {
+ m_elements_red = new AttributeStreamOfInt32(0);
m_envelopes_red = new ArrayList(0);
- else
+ } else {
+ m_elements_red.resizePreserveCapacity(0);
m_envelopes_red.clear();
+ }
}
- void addRedEnvelope(Envelope2D red_envelope) {
+ void addRedEnvelope(int element, Envelope2D red_envelope) {
if (!m_b_add_red)
throw new GeometryException("invalid call");
- m_envelopes_red.add(red_envelope);
+ Envelope2D e = new Envelope2D();
+ e.setCoords(red_envelope);
+ m_elements_red.add(element);
+ m_envelopes_red.add(e);
}
void endRedConstruction() {
@@ -87,8 +99,7 @@ void endRedConstruction() {
m_b_add_red = false;
- if (m_envelopes_red != null && m_envelopes_red.size() > 0
- && m_envelopes_blue != null && m_envelopes_blue.size() > 0) {
+ if (m_envelopes_red != null && m_envelopes_red.size() > 0 && m_envelopes_blue != null && m_envelopes_blue.size() > 0) {
if (m_function == -1)
m_function = State.initializeRedBlue;
else if (m_function == State.initializeBlue)
@@ -104,17 +115,23 @@ void startBlueConstruction() {
reset_();
m_b_add_blue = true;
- if (m_envelopes_blue == null)
+ if (m_envelopes_blue == null) {
+ m_elements_blue = new AttributeStreamOfInt32(0);
m_envelopes_blue = new ArrayList(0);
- else
+ } else {
+ m_elements_blue.resizePreserveCapacity(0);
m_envelopes_blue.clear();
+ }
}
- void addBlueEnvelope(Envelope2D blue_envelope) {
+ void addBlueEnvelope(int element, Envelope2D blue_envelope) {
if (!m_b_add_blue)
throw new GeometryException("invalid call");
- m_envelopes_blue.add(blue_envelope);
+ Envelope2D e = new Envelope2D();
+ e.setCoords(blue_envelope);
+ m_elements_blue.add(element);
+ m_envelopes_blue.add(e);
}
void endBlueConstruction() {
@@ -123,8 +140,7 @@ void endBlueConstruction() {
m_b_add_blue = false;
- if (m_envelopes_red != null && m_envelopes_red.size() > 0
- && m_envelopes_blue != null && m_envelopes_blue.size() > 0) {
+ if (m_envelopes_red != null && m_envelopes_red.size() > 0 && m_envelopes_blue != null && m_envelopes_blue.size() > 0) {
if (m_function == -1)
m_function = State.initializeRedBlue;
else if (m_function == State.initializeRed)
@@ -202,7 +218,7 @@ boolean next() {
b_searching = resetBlue_();
break;
default:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
@@ -236,6 +252,20 @@ void setTolerance(double tolerance) {
m_tolerance = tolerance;
}
+ /*
+ * Returns a reference to the envelope at the given handle. Use this for the red/red intersection case.
+ */
+ Envelope2D getEnvelope(int handle) {
+ return m_envelopes_red.get(handle);
+ }
+
+ /*
+ * Returns the user element associated with handle. Use this for the red/red intersection case.
+ */
+ int getElement(int handle) {
+ return m_elements_red.read(handle);
+ }
+
/*
* Returns a reference to the red envelope at handle_a.
*/
@@ -250,9 +280,21 @@ Envelope2D getBlueEnvelope(int handle_b) {
return m_envelopes_blue.get(handle_b);
}
+ /*
+ * Returns the user element associated with handle_a.
+ */
+ int getRedElement(int handle_a) {
+ return m_elements_red.read(handle_a);
+ }
+
+ /*
+ * Returns the user element associated with handle_b.
+ */
+ int getBlueElement(int handle_b) {
+ return m_elements_blue.read(handle_b);
+ }
+
private double m_tolerance;
- private ArrayList m_envelopes_red;
- private ArrayList m_envelopes_blue;
private int m_sweep_index_red;
private int m_sweep_index_blue;
private int m_envelope_handle_a;
@@ -263,6 +305,11 @@ Envelope2D getBlueEnvelope(int handle_b) {
private IntervalTreeImpl.IntervalTreeIteratorImpl m_iterator_blue;
private Envelope2D m_envelope_helper = new Envelope2D();
+ private ArrayList m_envelopes_red;
+ private ArrayList m_envelopes_blue;
+ private AttributeStreamOfInt32 m_elements_red;
+ private AttributeStreamOfInt32 m_elements_blue;
+
private AttributeStreamOfInt32 m_sorted_end_indices_red;
private AttributeStreamOfInt32 m_sorted_end_indices_blue;
@@ -274,8 +321,7 @@ Envelope2D getBlueEnvelope(int handle_b) {
private boolean m_b_add_red;
private boolean m_b_add_blue;
private boolean m_b_add_red_red;
-
- boolean m_b_done;
+ private boolean m_b_done;
private static boolean isTop_(int y_end_point_handle) {
return (y_end_point_handle & 0x1) == 1;
@@ -308,16 +354,14 @@ private boolean initialize_() {
if (m_interval_tree_red == null) {
m_interval_tree_red = new IntervalTreeImpl(true);
- m_iterator_red = m_interval_tree_red.getIterator();
m_sorted_end_indices_red = new AttributeStreamOfInt32(0);
}
- m_interval_tree_red.startConstruction();
- for (int i = 0; i < m_envelopes_red.size(); i++) {
- Envelope2D env = m_envelopes_red.get(i);
- m_interval_tree_red.addInterval(env.xmin, env.xmax);
+ m_interval_tree_red.addEnvelopesRef(m_envelopes_red);
+
+ if (m_iterator_red == null) {
+ m_iterator_red = m_interval_tree_red.getIterator();
}
- m_interval_tree_red.endConstruction();
m_sorted_end_indices_red.reserve(2 * m_envelopes_red.size());
m_sorted_end_indices_red.resize(0);
@@ -325,8 +369,7 @@ private boolean initialize_() {
for (int i = 0; i < 2 * m_envelopes_red.size(); i++)
m_sorted_end_indices_red.add(i);
- sortYEndIndices_(m_sorted_end_indices_red, 0,
- 2 * m_envelopes_red.size(), true);
+ sortYEndIndices_(m_sorted_end_indices_red, 0, 2 * m_envelopes_red.size(), true);
m_sweep_index_red = 2 * m_envelopes_red.size();
@@ -347,16 +390,14 @@ private boolean initializeRed_() {
if (m_interval_tree_red == null) {
m_interval_tree_red = new IntervalTreeImpl(true);
- m_iterator_red = m_interval_tree_red.getIterator();
m_sorted_end_indices_red = new AttributeStreamOfInt32(0);
}
- m_interval_tree_red.startConstruction();
- for (int i = 0; i < m_envelopes_red.size(); i++) {
- Envelope2D env = m_envelopes_red.get(i);
- m_interval_tree_red.addInterval(env.xmin, env.xmax);
+ m_interval_tree_red.addEnvelopesRef(m_envelopes_red);
+
+ if (m_iterator_red == null) {
+ m_iterator_red = m_interval_tree_red.getIterator();
}
- m_interval_tree_red.endConstruction();
m_sorted_end_indices_red.reserve(2 * m_envelopes_red.size());
m_sorted_end_indices_red.resize(0);
@@ -364,8 +405,7 @@ private boolean initializeRed_() {
for (int i = 0; i < 2 * m_envelopes_red.size(); i++)
m_sorted_end_indices_red.add(i);
- sortYEndIndices_(m_sorted_end_indices_red, 0,
- m_sorted_end_indices_red.size(), true);
+ sortYEndIndices_(m_sorted_end_indices_red, 0, m_sorted_end_indices_red.size(), true);
m_sweep_index_red = m_sorted_end_indices_red.size();
if (m_queued_list_red != -1) {
@@ -391,16 +431,14 @@ private boolean initializeBlue_() {
if (m_interval_tree_blue == null) {
m_interval_tree_blue = new IntervalTreeImpl(true);
- m_iterator_blue = m_interval_tree_blue.getIterator();
m_sorted_end_indices_blue = new AttributeStreamOfInt32(0);
}
- m_interval_tree_blue.startConstruction();
- for (int i = 0; i < m_envelopes_blue.size(); i++) {
- Envelope2D env = m_envelopes_blue.get(i);
- m_interval_tree_blue.addInterval(env.xmin, env.xmax);
+ m_interval_tree_blue.addEnvelopesRef(m_envelopes_blue);
+
+ if (m_iterator_blue == null) {
+ m_iterator_blue = m_interval_tree_blue.getIterator();
}
- m_interval_tree_blue.endConstruction();
m_sorted_end_indices_blue.reserve(2 * m_envelopes_blue.size());
m_sorted_end_indices_blue.resize(0);
@@ -408,8 +446,7 @@ private boolean initializeBlue_() {
for (int i = 0; i < 2 * m_envelopes_blue.size(); i++)
m_sorted_end_indices_blue.add(i);
- sortYEndIndices_(m_sorted_end_indices_blue, 0,
- m_sorted_end_indices_blue.size(), false);
+ sortYEndIndices_(m_sorted_end_indices_blue, 0, m_sorted_end_indices_blue.size(), false);
m_sweep_index_blue = m_sorted_end_indices_blue.size();
if (m_queued_list_blue != -1) {
@@ -435,29 +472,24 @@ private boolean initializeRedBlue_() {
if (m_interval_tree_red == null) {
m_interval_tree_red = new IntervalTreeImpl(true);
- m_iterator_red = m_interval_tree_red.getIterator();
m_sorted_end_indices_red = new AttributeStreamOfInt32(0);
}
if (m_interval_tree_blue == null) {
m_interval_tree_blue = new IntervalTreeImpl(true);
- m_iterator_blue = m_interval_tree_blue.getIterator();
m_sorted_end_indices_blue = new AttributeStreamOfInt32(0);
}
- m_interval_tree_red.startConstruction();
- for (int i = 0; i < m_envelopes_red.size(); i++) {
- Envelope2D env = m_envelopes_red.get(i);
- m_interval_tree_red.addInterval(env.xmin, env.xmax);
+ m_interval_tree_red.addEnvelopesRef(m_envelopes_red);
+ m_interval_tree_blue.addEnvelopesRef(m_envelopes_blue);
+
+ if (m_iterator_red == null) {
+ m_iterator_red = m_interval_tree_red.getIterator();
}
- m_interval_tree_red.endConstruction();
- m_interval_tree_blue.startConstruction();
- for (int i = 0; i < m_envelopes_blue.size(); i++) {
- Envelope2D env = m_envelopes_blue.get(i);
- m_interval_tree_blue.addInterval(env.xmin, env.xmax);
+ if (m_iterator_blue == null) {
+ m_iterator_blue = m_interval_tree_blue.getIterator();
}
- m_interval_tree_blue.endConstruction();
m_sorted_end_indices_red.reserve(2 * m_envelopes_red.size());
m_sorted_end_indices_blue.reserve(2 * m_envelopes_blue.size());
@@ -470,10 +502,8 @@ private boolean initializeRedBlue_() {
for (int i = 0; i < 2 * m_envelopes_blue.size(); i++)
m_sorted_end_indices_blue.add(i);
- sortYEndIndices_(m_sorted_end_indices_red, 0,
- m_sorted_end_indices_red.size(), true);
- sortYEndIndices_(m_sorted_end_indices_blue, 0,
- m_sorted_end_indices_blue.size(), false);
+ sortYEndIndices_(m_sorted_end_indices_red, 0, m_sorted_end_indices_red.size(), true);
+ sortYEndIndices_(m_sorted_end_indices_blue, 0, m_sorted_end_indices_blue.size(), false);
m_sweep_index_red = m_sorted_end_indices_red.size();
m_sweep_index_blue = m_sorted_end_indices_blue.size();
@@ -496,8 +526,7 @@ private boolean initializeRedBlue_() {
}
private boolean sweep_() {
- int y_end_point_handle = m_sorted_end_indices_red
- .get(--m_sweep_index_red);
+ int y_end_point_handle = m_sorted_end_indices_red.get(--m_sweep_index_red);
int envelope_handle = y_end_point_handle >> 1;
if (isBottom_(y_end_point_handle)) {
@@ -513,17 +542,14 @@ private boolean sweep_() {
return true;
}
- m_iterator_red.resetIterator(m_envelopes_red.get(envelope_handle).xmin,
- m_envelopes_red.get(envelope_handle).xmax, m_tolerance);
+ m_iterator_red.resetIterator(m_envelopes_red.get(envelope_handle).xmin, m_envelopes_red.get(envelope_handle).xmax, m_tolerance);
m_envelope_handle_a = envelope_handle;
m_function = State.iterate;
return true;
}
- private boolean sweepBruteForce_() {// this isn't really a sweep, it just
- // walks along the array of red
- // envelopes backward.
+ private boolean sweepBruteForce_() {// this isn't really a sweep, it just walks along the array of red envelopes backward.
if (--m_sweep_index_red == -1) {
m_envelope_handle_a = -1;
m_envelope_handle_b = -1;
@@ -538,9 +564,7 @@ private boolean sweepBruteForce_() {// this isn't really a sweep, it just
return true;
}
- private boolean sweepRedBlueBruteForce_() {// this isn't really a sweep, it
- // just walks along the array of
- // red envelopes backward.
+ private boolean sweepRedBlueBruteForce_() {// this isn't really a sweep, it just walks along the array of red envelopes backward.
if (--m_sweep_index_red == -1) {
m_envelope_handle_a = -1;
m_envelope_handle_b = -1;
@@ -555,13 +579,9 @@ private boolean sweepRedBlueBruteForce_() {// this isn't really a sweep, it
return true;
}
- private boolean sweepRedBlue_() {// controls whether we want to sweep the
- // red envelopes or sweep the blue
- // envelopes
- int y_end_point_handle_red = m_sorted_end_indices_red
- .get(m_sweep_index_red - 1);
- int y_end_point_handle_blue = m_sorted_end_indices_blue
- .get(m_sweep_index_blue - 1);
+ private boolean sweepRedBlue_() {// controls whether we want to sweep the red envelopes or sweep the blue envelopes
+ int y_end_point_handle_red = m_sorted_end_indices_red.get(m_sweep_index_red - 1);
+ int y_end_point_handle_blue = m_sorted_end_indices_blue.get(m_sweep_index_blue - 1);
double y_red = getAdjustedValue_(y_end_point_handle_red, true);
double y_blue = getAdjustedValue_(y_end_point_handle_blue, false);
@@ -576,20 +596,16 @@ private boolean sweepRedBlue_() {// controls whether we want to sweep the
if (isTop_(y_end_point_handle_blue))
return sweepBlue_();
- return sweepRed_(); // arbitrary. can call sweep_blue_ instead and would
- // also work correctly
+ return sweepRed_(); // arbitrary. can call sweep_blue_ instead and would also work correctly
}
private boolean sweepRed_() {
- int y_end_point_handle_red = m_sorted_end_indices_red
- .get(--m_sweep_index_red);
+ int y_end_point_handle_red = m_sorted_end_indices_red.get(--m_sweep_index_red);
int envelope_handle_red = y_end_point_handle_red >> 1;
if (isBottom_(y_end_point_handle_red)) {
- if (m_queued_list_red != -1
- && m_queued_indices_red.get(envelope_handle_red) != -1) {
- m_queued_envelopes.deleteElement(m_queued_list_red,
- m_queued_indices_red.get(envelope_handle_red));
+ if (m_queued_list_red != -1 && m_queued_indices_red.get(envelope_handle_red) != -1) {
+ m_queued_envelopes.deleteElement(m_queued_list_red, m_queued_indices_red.get(envelope_handle_red));
m_queued_indices_red.set(envelope_handle_red, -1);
} else
m_interval_tree_red.remove(envelope_handle_red);
@@ -604,8 +620,7 @@ private boolean sweepRed_() {
return true;
}
- if (m_queued_list_blue != -1
- && m_queued_envelopes.getListSize(m_queued_list_blue) > 0) {
+ if (m_queued_list_blue != -1 && m_queued_envelopes.getListSize(m_queued_list_blue) > 0) {
int node = m_queued_envelopes.getFirst(m_queued_list_blue);
while (node != -1) {
int e = m_queued_envelopes.getData(node);
@@ -618,9 +633,7 @@ private boolean sweepRed_() {
}
if (m_interval_tree_blue.size() > 0) {
- m_iterator_blue.resetIterator(
- m_envelopes_red.get(envelope_handle_red).xmin,
- m_envelopes_red.get(envelope_handle_red).xmax, m_tolerance);
+ m_iterator_blue.resetIterator(m_envelopes_red.get(envelope_handle_red).xmin, m_envelopes_red.get(envelope_handle_red).xmax, m_tolerance);
m_envelope_handle_a = envelope_handle_red;
m_function = State.iterateBlue;
} else {
@@ -634,8 +647,7 @@ private boolean sweepRed_() {
m_queued_list_red = m_queued_envelopes.createList(1);
}
- m_queued_indices_red.set(envelope_handle_red, m_queued_envelopes
- .addElement(m_queued_list_red, envelope_handle_red));
+ m_queued_indices_red.set(envelope_handle_red, m_queued_envelopes.addElement(m_queued_list_red, envelope_handle_red));
m_function = State.sweepRedBlue;
}
@@ -643,15 +655,12 @@ private boolean sweepRed_() {
}
private boolean sweepBlue_() {
- int y_end_point_handle_blue = m_sorted_end_indices_blue
- .get(--m_sweep_index_blue);
+ int y_end_point_handle_blue = m_sorted_end_indices_blue.get(--m_sweep_index_blue);
int envelope_handle_blue = y_end_point_handle_blue >> 1;
if (isBottom_(y_end_point_handle_blue)) {
- if (m_queued_list_blue != -1
- && m_queued_indices_blue.get(envelope_handle_blue) != -1) {
- m_queued_envelopes.deleteElement(m_queued_list_blue,
- m_queued_indices_blue.get(envelope_handle_blue));
+ if (m_queued_list_blue != -1 && m_queued_indices_blue.get(envelope_handle_blue) != -1) {
+ m_queued_envelopes.deleteElement(m_queued_list_blue, m_queued_indices_blue.get(envelope_handle_blue));
m_queued_indices_blue.set(envelope_handle_blue, -1);
} else
m_interval_tree_blue.remove(envelope_handle_blue);
@@ -666,8 +675,7 @@ private boolean sweepBlue_() {
return true;
}
- if (m_queued_list_red != -1
- && m_queued_envelopes.getListSize(m_queued_list_red) > 0) {
+ if (m_queued_list_red != -1 && m_queued_envelopes.getListSize(m_queued_list_red) > 0) {
int node = m_queued_envelopes.getFirst(m_queued_list_red);
while (node != -1) {
int e = m_queued_envelopes.getData(node);
@@ -680,10 +688,7 @@ private boolean sweepBlue_() {
}
if (m_interval_tree_red.size() > 0) {
- m_iterator_red.resetIterator(
- m_envelopes_blue.get(envelope_handle_blue).xmin,
- m_envelopes_blue.get(envelope_handle_blue).xmax,
- m_tolerance);
+ m_iterator_red.resetIterator(m_envelopes_blue.get(envelope_handle_blue).xmin, m_envelopes_blue.get(envelope_handle_blue).xmax, m_tolerance);
m_envelope_handle_b = envelope_handle_blue;
m_function = State.iterateRed;
} else {
@@ -697,8 +702,7 @@ private boolean sweepBlue_() {
m_queued_list_blue = m_queued_envelopes.createList(0);
}
- m_queued_indices_blue.set(envelope_handle_blue, m_queued_envelopes
- .addElement(m_queued_list_blue, envelope_handle_blue));
+ m_queued_indices_blue.set(envelope_handle_blue, m_queued_envelopes.addElement(m_queued_list_blue, envelope_handle_blue));
m_function = State.sweepRedBlue;
}
@@ -725,8 +729,7 @@ private boolean iterateRed_() {
m_envelope_handle_a = -1;
m_envelope_handle_b = -1;
- int envelope_handle_blue = m_sorted_end_indices_blue
- .get(m_sweep_index_blue) >> 1;
+ int envelope_handle_blue = m_sorted_end_indices_blue.get(m_sweep_index_blue) >> 1;
m_interval_tree_blue.insert(envelope_handle_blue);
m_function = State.sweepRedBlue;
@@ -738,8 +741,7 @@ private boolean iterateBlue_() {
if (m_envelope_handle_b != -1)
return false;
- int envelope_handle_red = m_sorted_end_indices_red
- .get(m_sweep_index_red) >> 1;
+ int envelope_handle_red = m_sorted_end_indices_red.get(m_sweep_index_red) >> 1;
m_interval_tree_red.insert(envelope_handle_red);
m_function = State.sweepRedBlue;
@@ -849,18 +851,15 @@ private interface State {
// *********** Helpers for Bucket sort**************
private BucketSort m_bucket_sort;
- private void sortYEndIndices_(AttributeStreamOfInt32 end_indices,
- int begin_, int end_, boolean b_red) {
+ private void sortYEndIndices_(AttributeStreamOfInt32 end_indices, int begin_, int end_, boolean b_red) {
if (m_bucket_sort == null)
m_bucket_sort = new BucketSort();
- Envelope2DBucketSortHelper sorter = new Envelope2DBucketSortHelper(
- this, b_red);
+ Envelope2DBucketSortHelper sorter = new Envelope2DBucketSortHelper(this, b_red);
m_bucket_sort.sort(end_indices, begin_, end_, sorter);
}
- private void sortYEndIndicesHelper_(AttributeStreamOfInt32 end_indices,
- int begin_, int end_, boolean b_red) {
+ private void sortYEndIndicesHelper_(AttributeStreamOfInt32 end_indices, int begin_, int end_, boolean b_red) {
end_indices.Sort(begin_, end_, new EndPointsComparer(this, b_red));
}
@@ -868,19 +867,17 @@ private double getAdjustedValue_(int e, boolean b_red) {
double dy = 0.5 * m_tolerance;
if (b_red) {
Envelope2D envelope_red = m_envelopes_red.get(e >> 1);
- double y = (isBottom_(e) ? envelope_red.ymin - dy
- : envelope_red.ymax + dy);
+ double y = (isBottom_(e) ? envelope_red.ymin - dy : envelope_red.ymax + dy);
return y;
}
Envelope2D envelope_blue = m_envelopes_blue.get(e >> 1);
- double y = (isBottom_(e) ? envelope_blue.ymin - dy : envelope_blue.ymax
- + dy);
+ double y = (isBottom_(e) ? envelope_blue.ymin - dy : envelope_blue.ymax + dy);
return y;
}
- private static final class EndPointsComparer extends
- AttributeStreamOfInt32.IntComparator {// For user sort
+ private static final class EndPointsComparer extends AttributeStreamOfInt32.IntComparator {// For user sort
+
EndPointsComparer(Envelope2DIntersectorImpl intersector, boolean b_red) {
m_intersector = intersector;
m_b_red = b_red;
@@ -902,10 +899,10 @@ public int compare(int e_1, int e_2) {
}
private static final class Envelope2DBucketSortHelper extends ClassicSort {// For
- // bucket
- // sort
- Envelope2DBucketSortHelper(Envelope2DIntersectorImpl intersector,
- boolean b_red) {
+
+ // bucket
+ // sort
+ Envelope2DBucketSortHelper(Envelope2DIntersectorImpl intersector, boolean b_red) {
m_intersector = intersector;
m_b_red = b_red;
}
diff --git a/src/com/esri/core/geometry/Envelope3D.java b/src/main/java/com/esri/core/geometry/Envelope3D.java
similarity index 54%
rename from src/com/esri/core/geometry/Envelope3D.java
rename to src/main/java/com/esri/core/geometry/Envelope3D.java
index 37edf611..6fa8b522 100644
--- a/src/com/esri/core/geometry/Envelope3D.java
+++ b/src/main/java/com/esri/core/geometry/Envelope3D.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,10 +25,14 @@
package com.esri.core.geometry;
+import java.io.Serializable;
+
/**
* A class that represents axis parallel 3D rectangle.
*/
-final class Envelope3D {
+public final class Envelope3D implements Serializable{
+ private static final long serialVersionUID = 1L;
+
public double xmin;
public double ymin;
@@ -43,20 +47,23 @@ final class Envelope3D {
public static Envelope3D construct(double _xmin, double _ymin,
double _zmin, double _xmax, double _ymax, double _zmax) {
- Envelope3D env = new Envelope3D();
- env.xmin = _xmin;
- env.ymin = _ymin;
- env.zmin = _zmin;
- env.xmax = _xmax;
- env.ymax = _ymax;
- env.zmax = _zmax;
+ Envelope3D env = new Envelope3D(_xmin, _ymin, _zmin, _xmax, _ymax, _zmax);
return env;
}
+ public Envelope3D(double _xmin, double _ymin, double _zmin, double _xmax, double _ymax, double _zmax) {
+ setCoords(_xmin, _ymin, _zmin, _xmax, _ymax, _zmax);
+ }
+
public Envelope3D() {
}
+ public Envelope3D(Envelope3D other) {
+ setCoords(other);
+ }
+
+
public void setInfinite() {
xmin = NumberUtils.negativeInf();
xmax = NumberUtils.positiveInf();
@@ -68,7 +75,11 @@ public void setInfinite() {
public void setEmpty() {
xmin = NumberUtils.NaN();
+ ymin = NumberUtils.NaN();
zmin = NumberUtils.NaN();
+ xmax = 0;
+ ymax = 0;
+ zmax = 0;
}
public boolean isEmpty() {
@@ -95,6 +106,7 @@ public void setCoords(double _xmin, double _ymin, double _zmin,
xmax = _xmax;
ymax = _ymax;
zmax = _zmax;
+ normalize();
}
public void setCoords(double _x, double _y, double _z) {
@@ -114,6 +126,24 @@ public void setCoords(Point3D center, double width, double height,
ymax = ymin + height;
zmin = center.z - depth * 0.5;
zmax = zmin + depth;
+ normalize();
+ }
+
+ public void setCoords(Envelope3D envSrc) {
+
+ setCoords(envSrc.xmin, envSrc.ymin, envSrc.zmin, envSrc.xmax, envSrc.ymax, envSrc.zmax);
+ }
+
+ public double getWidth() {
+ return xmax - xmin;
+ }
+
+ public double getHeight() {
+ return ymax - ymin;
+ }
+
+ public double getDepth() {
+ return zmax - zmin;
}
public void move(Point3D vector) {
@@ -125,6 +155,24 @@ public void move(Point3D vector) {
zmax += vector.z;
}
+ public void normalize() {
+ if (isEmpty())
+ return;
+
+ double min = Math.min(xmin, xmax);
+ double max = Math.max(xmin, xmax);
+ xmin = min;
+ xmax = max;
+ min = Math.min(ymin, ymax);
+ max = Math.max(ymin, ymax);
+ ymin = min;
+ ymax = max;
+ min = Math.min(zmin, zmax);
+ max = Math.max(zmin, zmax);
+ zmin = min;
+ zmax = max;
+ }
+
public void copyTo(Envelope2D env) {
env.xmin = xmin;
env.ymin = ymin;
@@ -170,7 +218,7 @@ public void merge(double x, double y, double z) {
public void merge(Point3D pt) {
merge(pt.x, pt.y, pt.z);
}
-
+
public void merge(Envelope3D other) {
if (other.isEmpty())
return;
@@ -185,6 +233,109 @@ public void merge(double x1, double y1, double z1, double x2, double y2,
merge(x2, y2, z2);
}
+ public void inflate(double dx, double dy, double dz) {
+ if (isEmpty())
+ return;
+ xmin -= dx;
+ xmax += dx;
+ ymin -= dy;
+ ymax += dy;
+ zmin -= dz;
+ zmax += dz;
+ if (xmin > xmax || ymin > ymax || zmin > zmax)
+ setEmpty();
+ }
+
+ /**
+ * Checks if this envelope intersects the other.
+ *
+ * @return True if this envelope intersects the other.
+ */
+ public boolean isIntersecting(Envelope3D other) {
+ return !isEmpty() && !other.isEmpty() && ((xmin <= other.xmin) ? xmax >= other.xmin : other.xmax >= xmin) && // check that x projections overlap
+ ((ymin <= other.ymin) ? ymax >= other.ymin : other.ymax >= ymin) && // check that y projections overlap
+ ((zmin <= other.zmin) ? zmax >= other.zmin : other.zmax >= zmin); // check that z projections overlap
+ }
+
+ /**
+ * Intersects this envelope with the other and stores result in this
+ * envelope.
+ *
+ * @return True if this envelope intersects the other, otherwise sets this
+ * envelope to empty state and returns False.
+ */
+ public boolean intersect(Envelope3D other) {
+ if (isEmpty() || other.isEmpty())
+ return false;
+
+ if (other.xmin > xmin)
+ xmin = other.xmin;
+
+ if (other.xmax < xmax)
+ xmax = other.xmax;
+
+ if (other.ymin > ymin)
+ ymin = other.ymin;
+
+ if (other.ymax < ymax)
+ ymax = other.ymax;
+
+ if (other.zmin > zmin)
+ zmin = other.zmin;
+
+ if (other.zmax < zmax)
+ zmax = other.zmax;
+
+ boolean bIntersecting = xmin <= xmax && ymin <= ymax && zmin <= zmax;
+
+ if (!bIntersecting)
+ setEmpty();
+
+ return bIntersecting;
+ }
+
+ /**
+ * Returns True if the envelope contains the other envelope (boundary
+ * inclusive).
+ */
+ public boolean contains(Envelope3D other) {// Note: Will return False, if either envelope is empty.
+ return other.xmin >= xmin && other.xmax <= xmax && other.ymin >= ymin && other.ymax <= ymax && other.zmin >= zmin && other.zmax <= zmax;
+ }
+
+ @Override
+ public boolean equals(Object _other) {
+ if (_other == this)
+ return true;
+
+ if (!(_other instanceof Envelope3D))
+ return false;
+
+ Envelope3D other = (Envelope3D) _other;
+ if (isEmpty() && other.isEmpty())
+ return true;
+
+ if (xmin != other.xmin || ymin != other.ymin || zmin != other.zmin || xmax != other.xmax || ymax != other.ymax || zmax != other.zmax)
+ return false;
+
+ return true;
+ }
+
+
+ @Override
+ public int hashCode() {
+ if (isEmpty()) {
+ return NumberUtils.hash(NumberUtils.TheNaN);
+ }
+
+ int hash = NumberUtils.hash(xmin);
+ hash = NumberUtils.hash(hash, xmax);
+ hash = NumberUtils.hash(hash, ymin);
+ hash = NumberUtils.hash(hash, ymax);
+ hash = NumberUtils.hash(hash, zmin);
+ hash = NumberUtils.hash(hash, zmax);
+ return hash;
+ }
+
public void construct(Envelope1D xinterval, Envelope1D yinterval,
Envelope1D zinterval) {
if (xinterval.isEmpty() || yinterval.isEmpty()) {
diff --git a/src/main/java/com/esri/core/geometry/GenericGeometrySerializer.java b/src/main/java/com/esri/core/geometry/GenericGeometrySerializer.java
new file mode 100644
index 00000000..c6bd2d09
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/GenericGeometrySerializer.java
@@ -0,0 +1,94 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+//This is a writeReplace class for MultiPoint, Polyline, and Polygon
+public class GenericGeometrySerializer implements Serializable {
+ private static final long serialVersionUID = 1L;
+ int geometryType;
+ byte[] esriShape = null;
+ int simpleFlag = 0;
+ double tolerance = 0;
+ boolean[] ogcFlags = null;
+
+ public Object readResolve() throws ObjectStreamException {
+ Geometry geometry = null;
+ try {
+ geometry = GeometryEngine.geometryFromEsriShape(
+ esriShape, Geometry.Type.intToType(geometryType));
+
+ if (Geometry.isMultiVertex(geometryType)) {
+ MultiVertexGeometryImpl mvImpl = (MultiVertexGeometryImpl) geometry
+ ._getImpl();
+ if (!geometry.isEmpty()
+ && Geometry.isMultiPath(geometryType)) {
+ MultiPathImpl mpImpl = (MultiPathImpl) geometry._getImpl();
+ AttributeStreamOfInt8 pathFlags = mpImpl
+ .getPathFlagsStreamRef();
+ for (int i = 0, n = mpImpl.getPathCount(); i < n; i++) {
+ if (ogcFlags[i])
+ pathFlags.setBits(i,
+ (byte) PathFlags.enumOGCStartPolygon);
+ }
+ }
+ mvImpl.setIsSimple(simpleFlag, tolerance, false);
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot read geometry from stream");
+ }
+ return geometry;
+ }
+
+ public void setGeometryByValue(Geometry geometry)
+ throws ObjectStreamException {
+ try {
+ esriShape = GeometryEngine
+ .geometryToEsriShape(geometry);
+ geometryType = geometry.getType().value();
+ if (Geometry.isMultiVertex(geometryType)) {
+ MultiVertexGeometryImpl mvImpl = (MultiVertexGeometryImpl) geometry
+ ._getImpl();
+ tolerance = mvImpl.m_simpleTolerance;
+ simpleFlag = mvImpl.getIsSimple(0);
+ if (!geometry.isEmpty()
+ && Geometry.isMultiPath(geometryType)) {
+ MultiPathImpl mpImpl = (MultiPathImpl) geometry._getImpl();
+ ogcFlags = new boolean[mpImpl.getPathCount()];
+ AttributeStreamOfInt8 pathFlags = mpImpl
+ .getPathFlagsStreamRef();
+ for (int i = 0, n = mpImpl.getPathCount(); i < n; i++) {
+ ogcFlags[i] = (pathFlags.read(i) & (byte) PathFlags.enumOGCStartPolygon) != 0;
+ }
+ }
+
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot serialize this geometry");
+ }
+ }
+}
diff --git a/src/com/esri/core/geometry/GeoDist.java b/src/main/java/com/esri/core/geometry/GeoDist.java
similarity index 98%
rename from src/com/esri/core/geometry/GeoDist.java
rename to src/main/java/com/esri/core/geometry/GeoDist.java
index 9a1b410d..b7845151 100644
--- a/src/com/esri/core/geometry/GeoDist.java
+++ b/src/main/java/com/esri/core/geometry/GeoDist.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -88,7 +88,7 @@ static private double q90(double a, double e2) {
double n2 = n * n;
return a / (1.0 + n)
- * (1.0 + n2 * (1. / 4. + n2 * (1. / 64. + n2 * (1. / 256.))))
+ * (1.0 + n2 * (1.0 / 4.0 + n2 * (1.0 / 64.0 + n2 * (1.0 / 256.0))))
* PE_PI2;
}
@@ -257,7 +257,7 @@ static public void geodesic_distance_ngs(double a, double e2, double lam1,
/* top of the long-line loop (kind = 1) */
q_continue_looping = true;
- while (q_continue_looping == true) {
+ while (q_continue_looping && it < 100) {
it = it + 1;
if (kind == 1) {
diff --git a/src/main/java/com/esri/core/geometry/GeoJsonCrsTables.java b/src/main/java/com/esri/core/geometry/GeoJsonCrsTables.java
new file mode 100644
index 00000000..aa35f20d
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/GeoJsonCrsTables.java
@@ -0,0 +1,183 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.util.Arrays;
+
+class GeoJsonCrsTables {
+ static int getWkidFromCrsShortForm(String crs_identifier) {
+ int last_colon = crs_identifier.lastIndexOf((int) ':'); // skip version
+
+ if (last_colon == -1)
+ return -1;
+
+ int code_start = last_colon + 1;
+ int wkid = getWkidFromCrsCode_(crs_identifier, code_start);
+ return wkid;
+ }
+
+ static int getWkidFromCrsName(String crs_identifier) {
+ int wkid = -1;
+
+ int last_colon = crs_identifier.lastIndexOf((int) ':'); // skip
+ // authority,
+ // version, and
+ // other things.
+ // Just try to
+ // get a wkid.
+ // This works
+ // for
+ // short/long
+ // form.
+
+ if (last_colon == -1)
+ return -1;
+
+ int code_start = last_colon + 1;
+ wkid = getWkidFromCrsCode_(crs_identifier, code_start);
+
+ if (wkid != -1)
+ return wkid;
+
+ wkid = getWkidFromCrsOgcUrn(crs_identifier); // could be an OGC
+ // "preferred" urn
+ return wkid;
+ }
+
+ static int getWkidFromCrsOgcUrn(String crs_identifier) {
+ int wkid = -1;
+ if (crs_identifier.regionMatches(0, "urn:ogc:def:crs:OGC", 0, 19))
+ wkid = getWkidFromCrsOgcUrn_(crs_identifier);
+
+ return wkid;
+ }
+
+ private static int getWkidFromCrsCode_(String crs_identifier, int code_start) {
+ assert(code_start > 0);
+
+ int wkid = -1;
+ int code_count = crs_identifier.length() - code_start;
+
+ try {
+ wkid = Integer.parseInt(crs_identifier.substring(code_start, code_start + code_count));
+ } catch (Exception e) {
+ }
+
+ return (int) wkid;
+ }
+
+ private static int getWkidFromCrsOgcUrn_(String crs_identifier) {
+ assert(crs_identifier.regionMatches(0, "urn:ogc:def:crs:OGC", 0, 19));
+
+ int last_colon = crs_identifier.lastIndexOf((int) ':'); // skip version
+
+ if (last_colon == -1)
+ return -1;
+
+ int ogc_code_start = last_colon + 1;
+ int ogc_code_count = crs_identifier.length() - ogc_code_start;
+
+ if (crs_identifier.regionMatches(ogc_code_start, "CRS84", 0, ogc_code_count))
+ return 4326;
+
+ if (crs_identifier.regionMatches(ogc_code_start, "CRS83", 0, ogc_code_count))
+ return 4269;
+
+ if (crs_identifier.regionMatches(ogc_code_start, "CRS27", 0, ogc_code_count))
+ return 4267;
+
+ return -1;
+ }
+
+ static int getWkidFromCrsHref(String crs_identifier) {
+ int sr_org_code_start = -1;
+
+ if (crs_identifier.regionMatches(0, "http://spatialreference.org/ref/epsg/", 0, 37))
+ sr_org_code_start = 37;
+ else if (crs_identifier.regionMatches(0, "www.spatialreference.org/ref/epsg/", 0, 34))
+ sr_org_code_start = 34;
+ else if (crs_identifier.regionMatches(0, "http://www.spatialreference.org/ref/epsg/", 0, 41))
+ sr_org_code_start = 41;
+
+ if (sr_org_code_start != -1) {
+ int sr_org_code_end = crs_identifier.indexOf('/', sr_org_code_start);
+
+ if (sr_org_code_end == -1)
+ return -1;
+
+ int count = sr_org_code_end - sr_org_code_start;
+ int wkid = -1;
+
+ try {
+ wkid = Integer.parseInt(crs_identifier.substring(sr_org_code_start, sr_org_code_start + count));
+ } catch (Exception e) {
+ }
+
+ return wkid;
+ }
+
+ int open_gis_epsg_slash_end = -1;
+
+ if (crs_identifier.regionMatches(0, "http://opengis.net/def/crs/EPSG/", 0, 32))
+ open_gis_epsg_slash_end = 32;
+ else if (crs_identifier.regionMatches(0, "www.opengis.net/def/crs/EPSG/", 0, 29))
+ open_gis_epsg_slash_end = 29;
+ else if (crs_identifier.regionMatches(0, "http://www.opengis.net/def/crs/EPSG/", 0, 36))
+ open_gis_epsg_slash_end = 36;
+
+ if (open_gis_epsg_slash_end != -1) {
+ int last_slash = crs_identifier.lastIndexOf('/'); // skip over the
+ // "0/"
+
+ if (last_slash == -1)
+ return -1;
+
+ int open_gis_code_start = last_slash + 1;
+
+ int count = crs_identifier.length() - open_gis_code_start;
+ int wkid = -1;
+
+ try {
+ wkid = Integer.parseInt(crs_identifier.substring(open_gis_code_start, open_gis_code_start + count));
+ } catch (Exception e) {
+ }
+
+ return wkid;
+ }
+
+ if (crs_identifier.compareToIgnoreCase("http://spatialreference.org/ref/sr-org/6928/ogcwkt/") == 0)
+ return 3857;
+
+ return -1;
+ }
+
+ static String getWktFromCrsName(String crs_identifier) {
+ int last_colon = crs_identifier.lastIndexOf((int) ':'); // skip
+ // authority
+ int wkt_start = last_colon + 1;
+ int wkt_count = crs_identifier.length() - wkt_start;
+ String wkt = crs_identifier.substring(wkt_start, wkt_start + wkt_count);
+ return wkt;
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/GeoJsonExportFlags.java b/src/main/java/com/esri/core/geometry/GeoJsonExportFlags.java
new file mode 100644
index 00000000..6290a0f6
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/GeoJsonExportFlags.java
@@ -0,0 +1,54 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+public interface GeoJsonExportFlags {
+ public static final int geoJsonExportDefaults = 0;
+ /**
+ * Export MultiXXX geometries every time, by default it will export the minimum required type.
+ */
+ public static final int geoJsonExportPreferMultiGeometry = 1;
+ public static final int geoJsonExportStripZs = 2;
+ public static final int geoJsonExportStripMs = 4;
+ public static final int geoJsonExportSkipCRS = 8;
+ public static final int geoJsonExportFailIfNotSimple = 16;
+ public static final int geoJsonExportPrecision16 = 0x02000;
+ public static final int geoJsonExportPrecision15 = 0x04000;
+ public static final int geoJsonExportPrecision14 = 0x06000;
+ public static final int geoJsonExportPrecision13 = 0x08000;
+ public static final int geoJsonExportPrecision12 = 0x0a000;
+ public static final int geoJsonExportPrecision11 = 0x0c000;
+ public static final int geoJsonExportPrecision10 = 0x0e000;
+ public static final int geoJsonExportPrecision9 = 0x10000;
+ public static final int geoJsonExportPrecision8 = 0x12000;
+ public static final int geoJsonExportPrecision7 = 0x14000;
+ public static final int geoJsonExportPrecision6 = 0x16000;
+ public static final int geoJsonExportPrecision5 = 0x18000;
+ public static final int geoJsonExportPrecision4 = 0x1a000;
+ public static final int geoJsonExportPrecision3 = 0x1c000;
+ public static final int geoJsonExportPrecision2 = 0x1e000;
+ public static final int geoJsonExportPrecision1 = 0x20000;
+ public static final int geoJsonExportPrecision0 = 0x22000;
+ public static final int geoJsonExportPrecisionFixedPoint = 0x40000;
+}
diff --git a/src/main/java/com/esri/core/geometry/GeoJsonImportFlags.java b/src/main/java/com/esri/core/geometry/GeoJsonImportFlags.java
new file mode 100644
index 00000000..5245bd96
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/GeoJsonImportFlags.java
@@ -0,0 +1,38 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+public interface GeoJsonImportFlags {
+ public static final int geoJsonImportDefaults = 0;
+ @Deprecated static final int geoJsonImportNonTrusted = 2;
+ /**
+ * If set, the import will skip CRS.
+ */
+ public static final int geoJsonImportSkipCRS = 8;
+ /**
+ * If set, and the geojson does not have a spatial reference, the result geometry will not have one too, otherwise
+ * it'll assume WGS84.
+ */
+ public static final int geoJsonImportNoWGS84Default = 16;
+}
diff --git a/src/com/esri/core/geometry/GeodeticCurveType.java b/src/main/java/com/esri/core/geometry/GeodeticCurveType.java
similarity index 79%
rename from src/com/esri/core/geometry/GeodeticCurveType.java
rename to src/main/java/com/esri/core/geometry/GeodeticCurveType.java
index b39d57fd..3dc053af 100644
--- a/src/com/esri/core/geometry/GeodeticCurveType.java
+++ b/src/main/java/com/esri/core/geometry/GeodeticCurveType.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -43,4 +43,9 @@ interface GeodeticCurveType {
*/
public final static int GreatElliptic = 2;
public final static int NormalSection = 3;
+ /*The ShapePreserving type means the segments shapes are preserved in the spatial reference where they are defined.
+ *The behavior of the ShapePreserving type can be emulated by densifying the geometry with a small step, and then calling a geodetic method
+ *using Geodesic or GreatElliptic curve types.
+ */
+ public final static int ShapePreserving = 4;
}
diff --git a/src/com/esri/core/geometry/Geometry.java b/src/main/java/com/esri/core/geometry/Geometry.java
similarity index 70%
rename from src/com/esri/core/geometry/Geometry.java
rename to src/main/java/com/esri/core/geometry/Geometry.java
index 5684368d..d108d328 100644
--- a/src/com/esri/core/geometry/Geometry.java
+++ b/src/main/java/com/esri/core/geometry/Geometry.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,19 +25,16 @@
package com.esri.core.geometry;
-import com.esri.core.geometry.VertexDescription.Semantics;
import java.io.ObjectStreamException;
import java.io.Serializable;
+import static com.esri.core.geometry.SizeOf.sizeOfDoubleArray;
+
/**
* Common properties and methods shared by all geometric objects. Geometries are
* objects that define a spatial location and and associated geometric shape.
*/
public abstract class Geometry implements Serializable {
- // Note: We use writeReplace with GeometrySerializer. This field is
- // irrelevant. Need to be removed after final.
- private static final long serialVersionUID = 2L;
-
VertexDescription m_description;
volatile int m_touchFlag;
@@ -49,8 +46,7 @@ public abstract class Geometry implements Serializable {
/**
* Geometry types
*/
- static interface GeometryType {
-
+ static public interface GeometryType {
public final static int Unknown = 0;
public final static int Point = 1 + 0x20; // points
public final static int Line = 2 + 0x40 + 0x100; // lines, segment
@@ -58,10 +54,10 @@ static interface GeometryType {
final static int EllipticArc = 4 + 0x40 + 0x100; // lines, segment
public final static int Envelope = 5 + 0x40 + 0x80; // lines, areas
public final static int MultiPoint = 6 + 0x20 + 0x200; // points,
- // multivertex
+ // multivertex
public final static int Polyline = 7 + 0x40 + 0x200 + 0x400; // lines,
// multivertex,
- // multipath
+ // multipath
public final static int Polygon = 8 + 0x40 + 0x80 + 0x200 + 0x400;
}
@@ -117,6 +113,18 @@ public int value() {
Type(int val) {
enumValue = val;
}
+
+ static public Geometry.Type intToType(int geometryType)
+ {
+ Geometry.Type[] v = Geometry.Type.values();
+ for(int i = 0; i < v.length; i++)
+ {
+ if(v[i].value() == geometryType)
+ return v[i];
+ }
+
+ throw new IllegalArgumentException();
+ }
}
/**
@@ -125,7 +133,7 @@ public int value() {
* @return Returns the geometry type.
*/
public abstract Geometry.Type getType();
-
+
/**
* Returns the topological dimension of the geometry object based on the
* geometry's type.
@@ -143,7 +151,24 @@ public int value() {
public abstract int getDimension();
/**
- * Returns the VertexDescription of this geomtry.
+ * Returns an estimate of this object size in bytes.
+ *
+ * This estimate doesn't include the size of the {@link VertexDescription} object
+ * because instances of {@link VertexDescription} are shared among
+ * geometry objects.
+ *
+ * @return Returns an estimate of this object size in bytes.
+ */
+ public abstract long estimateMemorySize();
+
+ protected static long estimateMemorySize(double[] attributes)
+ {
+ return attributes != null ? sizeOfDoubleArray(attributes.length) : 0;
+ }
+
+ /**
+ * Returns the VertexDescription of this geometry.
+ * @return VertexDescription
*/
public VertexDescription getDescription() {
return m_description;
@@ -152,65 +177,41 @@ public VertexDescription getDescription() {
/**
* Assigns the new VertexDescription by adding or dropping attributes. The
* Geometry will have the src description as a result.
+ * @param src VertexDescription to assign.
*/
- void assignVertexDescription(VertexDescription src) {
+ public void assignVertexDescription(VertexDescription src) {
_touch();
if (src == m_description)
return;
- for (int i = Semantics.POSITION; i < Semantics.MAXSEMANTICS; i++) {
- if (m_description.hasAttribute(i) && (!src.hasAttribute(i)))
- _beforeDropAttributeImpl(i);
- }
-
- VertexDescription olddescription = m_description;
- m_description = src;
-
- for (int i = Semantics.POSITION; i < Semantics.MAXSEMANTICS; i++) {
- if (!olddescription.hasAttribute(i) && src.hasAttribute(i))
- _afterAddAttributeImpl(i);
- }
+ _assignVertexDescriptionImpl(src);
}
+
+ protected abstract void _assignVertexDescriptionImpl(VertexDescription src);
/**
* Merges the new VertexDescription by adding missing attributes from the
* src. The Geometry will have a union of the current and the src
* descriptions.
+ * @param src VertexDescription to merge.
*/
- void mergeVertexDescription(VertexDescription src) {
+ public void mergeVertexDescription(VertexDescription src) {
_touch();
if (src == m_description)
return;
// check if we need to do anything (if the src has same attributes)
- boolean bNeedAction = false;
- VertexDescriptionDesignerImpl vdd = null;
- for (int i = Semantics.POSITION; i < Semantics.MAXSEMANTICS; i++) {
- if (!m_description.hasAttribute(i) && src.hasAttribute(i)) {
- if (!bNeedAction) {
- bNeedAction = true;
- vdd = new VertexDescriptionDesignerImpl(m_description);
- }
-
- vdd.addAttribute(i);
- }
- }
-
- if (!bNeedAction)
+ VertexDescription newdescription = VertexDescriptionDesignerImpl.getMergedVertexDescription(m_description, src);
+ if (newdescription == m_description)
return;
-
- VertexDescription olddescription = m_description;
- m_description = vdd.getDescription();
- for (int i = Semantics.POSITION; i < Semantics.MAXSEMANTICS; i++) {
- if (!olddescription.hasAttribute(i)
- && m_description.hasAttribute(i)) {
- _afterAddAttributeImpl(i);
- }
- }
+
+ _assignVertexDescriptionImpl(newdescription);
}
/**
* A shortcut for getDescription().hasAttribute()
+ * @param semantics The VertexDescription.Semantics to check.
+ * @return Return true if the attribute is present.
*/
public boolean hasAttribute(int semantics) {
return getDescription().hasAttribute(semantics);
@@ -219,22 +220,15 @@ public boolean hasAttribute(int semantics) {
/**
* Adds a new attribute to the Geometry.
*
- * @param semantics
+ * @param semantics The VertexDescription.Semantics to add.
*/
public void addAttribute(int semantics) {
_touch();
if (m_description.hasAttribute(semantics))
return;
-
- // Create a designer instance out of existing description.
- VertexDescriptionDesignerImpl vdd = new VertexDescriptionDesignerImpl(
- m_description);
- // Add the attribute to the description designer.
- vdd.addAttribute(semantics);
- // Obtain new description.
- m_description = vdd.getDescription();
- // Let it be known we have added the attribute.
- _afterAddAttributeImpl(semantics);
+
+ VertexDescription newvd = VertexDescriptionDesignerImpl.getMergedVertexDescription(m_description, semantics);
+ _assignVertexDescriptionImpl(newvd);
}
/**
@@ -242,21 +236,15 @@ public void addAttribute(int semantics) {
* equivalent to setting the attribute to the default value for each vertex,
* However, it is faster and the result Geometry has smaller memory
* footprint and smaller size when persisted.
+ * @param semantics The VertexDescription.Semantics to drop.
*/
public void dropAttribute(int semantics) {
_touch();
if (!m_description.hasAttribute(semantics))
return;
- // Create a designer instance out of existing description.
- VertexDescriptionDesignerImpl vdd = new VertexDescriptionDesignerImpl(
- m_description);
- // Remove the attribute from the description designer.
- vdd.removeAttribute(semantics);
- // Let know we are dropping the attribute.
- _beforeDropAttributeImpl(semantics);
- // Obtain new description.
- m_description = vdd.getDescription();
+ VertexDescription newvd = VertexDescriptionDesignerImpl.removeSemanticsFromVertexDescription(m_description, semantics);
+ _assignVertexDescriptionImpl(newvd);
}
/**
@@ -268,7 +256,10 @@ public void dropAllAttributes() {
}
/**
- * Returns the min and max attribute values at the ordinate of the Geometry
+ * Returns the min and max attribute values at the ordinate of the Geometry.
+ * @param semantics The semantics of the interval.
+ * @param ordinate The ordinate of the interval.
+ * @return The interval.
*/
public abstract Envelope1D queryInterval(int semantics, int ordinate);
@@ -280,19 +271,17 @@ public void dropAllAttributes() {
*/
public abstract void queryEnvelope(Envelope env);
- // {
- // Envelope2D e2d = new Envelope2D();
- // queryEnvelope2D(e2d);
- // env.setEnvelope2D(e2d);
- // }
-
/**
* Returns tight bbox of the Geometry in X, Y plane.
+ * @param env
+ * The envelope to return the result in.
*/
public abstract void queryEnvelope2D(Envelope2D env);
/**
* Returns tight bbox of the Geometry in 3D.
+ * @param env
+ * The envelope to return the result in.
*/
abstract void queryEnvelope3D(Envelope3D env);
@@ -300,6 +289,8 @@ public void dropAllAttributes() {
* Returns the conservative bbox of the Geometry in X, Y plane. This is a
* faster method than QueryEnvelope2D. However, the bbox could be larger
* than the tight box.
+ * @param env
+ * The envelope to return the result in.
*/
public void queryLooseEnvelope2D(Envelope2D env) {
queryEnvelope2D(env);
@@ -309,6 +300,8 @@ public void queryLooseEnvelope2D(Envelope2D env) {
* Returns tight conservative box of the Geometry in 3D. This is a faster
* method than the QueryEnvelope3D. However, the box could be larger than
* the tight box.
+ * @param env
+ * The envelope to return the result in.
*/
void queryLooseEnvelope3D(Envelope3D env) {
queryEnvelope3D(env);
@@ -346,13 +339,14 @@ void queryLooseEnvelope3D(Envelope3D env) {
/**
* Creates an instance of an empty geometry of the same type.
+ * @return The new instance.
*/
public abstract Geometry createInstance();
/**
* Copies this geometry to another geometry of the same type. The result
* geometry is an exact copy.
- *
+ * @param dst The geometry instance to copy to.
* @exception GeometryException
* invalid_argument if the geometry is of different type.
*/
@@ -383,18 +377,6 @@ public double calculateLength2D() {
return 0;
}
- /*
- * Called before the new description pointer is set. Caller is supposed to
- * get rid of the Geometry attribute value.
- */
- abstract void _beforeDropAttributeImpl(int semantics);
-
- /*
- * Called after the new description pointer is set. Caller is supposed to
- * add the Geometry attribute value.
- */
- abstract void _afterAddAttributeImpl(int semantics);
-
protected Object _getImpl() {
throw new RuntimeException("invalid call");
}
@@ -474,7 +456,7 @@ public static int getDimensionFromType(int type) {
* @param type
* The integer value from geometry enumeration. You can use the
* method {@link Type#value()} to get at the integer value.
- * @return TRUE if the geometry is a point.
+ * @return TRUE if the geometry is a point (a Point or a Multipoint).
*/
public static boolean isPoint(int type) {
return (type & 0x20) != 0;
@@ -555,6 +537,25 @@ public Geometry copy() {
return geom;
}
+ /**
+ * Returns boundary of this geometry.
+ *
+ * Polygon and Envelope boundary is a Polyline. For Polyline and Line, the
+ * boundary is a Multi_point consisting of path end points. For Multi_point and
+ * Point null is returned.
+ * @return The boundary geometry.
+ */
+ public abstract Geometry getBoundary();
+
+ /**
+ * Replaces NaNs in the attribute with the given value.
+ * If the geometry is not empty, it adds the attribute if geometry does not have it yet, and replaces the values.
+ * If the geometry is empty, it adds the attribute and does not set any values.
+ * @param semantics The semantics for which to replace the NaNs.
+ * @param value The value to replace NaNs with.
+ */
+ public abstract void replaceNaNs(int semantics, double value);
+
static Geometry _clone(Geometry src) {
Geometry geom = src.createInstance();
src.copyTo(geom);
@@ -581,20 +582,92 @@ synchronized void _touch() {
/**
* Describes the degree of acceleration of the geometry.
+ * Acceleration usually builds a raster and a quadtree.
*/
static public enum GeometryAccelerationDegree {
- enumMild, // 200) {
+ return snippet.substring(0, 197) + "... ("+snippet.length()+" characters)";
+ }
+ else {
+ return snippet;
+ }
+ }
+
+ /**
+ * Returns count of geometry vertices: 1 for Point, 4 for Envelope,
+ * get_point_count for MultiVertexGeometry types, 2 for segment types Returns 0
+ * if geometry is empty.
+ * @param geom The geometry to get the vertex count for.
+ * @return The vertex count.
+ */
+ public static int vertex_count(Geometry geom) {
+ Geometry.Type gt = geom.getType();
+ if (Geometry.isMultiVertex(gt.value()))
+ return ((MultiVertexGeometry) geom).getPointCount();
+
+ if (geom.isEmpty())
+ return 0;
+
+ if (gt == Geometry.Type.Envelope)
+ return 4;
+
+ if (gt == Geometry.Type.Point)
+ return 1;
+
+ if (Geometry.isSegment(gt.value()))
+ return 2;
+
+ throw new GeometryException("missing type");
+ }
+
}
diff --git a/src/main/java/com/esri/core/geometry/GeometryAccelerators.java b/src/main/java/com/esri/core/geometry/GeometryAccelerators.java
new file mode 100644
index 00000000..90d699d0
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/GeometryAccelerators.java
@@ -0,0 +1,92 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+class GeometryAccelerators {
+
+ private RasterizedGeometry2D m_rasterizedGeometry;
+ private QuadTreeImpl m_quad_tree;
+ private QuadTreeImpl m_quad_tree_for_paths;
+
+ public RasterizedGeometry2D getRasterizedGeometry() {
+ return m_rasterizedGeometry;
+ }
+
+ public QuadTreeImpl getQuadTree() {
+ return m_quad_tree;
+ }
+
+ public QuadTreeImpl getQuadTreeForPaths() {
+ return m_quad_tree_for_paths;
+ }
+
+ void _setRasterizedGeometry(RasterizedGeometry2D rg) {
+ m_rasterizedGeometry = rg;
+ }
+
+ void _setQuadTree(QuadTreeImpl quad_tree) {
+ m_quad_tree = quad_tree;
+ }
+
+ void _setQuadTreeForPaths(QuadTreeImpl quad_tree) { m_quad_tree_for_paths = quad_tree; }
+
+ static boolean canUseRasterizedGeometry(Geometry geom) {
+ if (geom.isEmpty()
+ || !(geom.getType() == Geometry.Type.Polyline || geom.getType() == Geometry.Type.Polygon)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean canUseQuadTree(Geometry geom) {
+ if (geom.isEmpty()
+ || !(geom.getType() == Geometry.Type.Polyline || geom.getType() == Geometry.Type.Polygon)) {
+ return false;
+ }
+
+ if (((MultiVertexGeometry) geom).getPointCount() < 20) {
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean canUseQuadTreeForPaths(Geometry geom) {
+ if (geom.isEmpty() || !(geom.getType() == Geometry.Type.Polyline || geom.getType() == Geometry.Type.Polygon))
+ return false;
+
+ if (((MultiVertexGeometry) geom).getPointCount() < 20)
+ return false;
+
+ return true;
+ }
+
+ public long estimateMemorySize()
+ {
+ return (m_rasterizedGeometry != null ? m_rasterizedGeometry.estimateMemorySize() : 0) +
+ (m_quad_tree != null ? m_quad_tree.estimateMemorySize() : 0) +
+ (m_quad_tree_for_paths != null ? m_quad_tree_for_paths.estimateMemorySize() : 0);
+ }
+}
diff --git a/src/com/esri/core/geometry/GeometryCursor.java b/src/main/java/com/esri/core/geometry/GeometryCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/GeometryCursor.java
rename to src/main/java/com/esri/core/geometry/GeometryCursor.java
index 503dfe4c..3c2ef5d6 100644
--- a/src/com/esri/core/geometry/GeometryCursor.java
+++ b/src/main/java/com/esri/core/geometry/GeometryCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/GeometryCursorAppend.java b/src/main/java/com/esri/core/geometry/GeometryCursorAppend.java
similarity index 98%
rename from src/com/esri/core/geometry/GeometryCursorAppend.java
rename to src/main/java/com/esri/core/geometry/GeometryCursorAppend.java
index cbf3faee..dec0b708 100644
--- a/src/com/esri/core/geometry/GeometryCursorAppend.java
+++ b/src/main/java/com/esri/core/geometry/GeometryCursorAppend.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/GeometryEngine.java b/src/main/java/com/esri/core/geometry/GeometryEngine.java
similarity index 84%
rename from src/com/esri/core/geometry/GeometryEngine.java
rename to src/main/java/com/esri/core/geometry/GeometryEngine.java
index c8fec93c..99466fd2 100644
--- a/src/com/esri/core/geometry/GeometryEngine.java
+++ b/src/main/java/com/esri/core/geometry/GeometryEngine.java
@@ -1,829 +1,908 @@
-/*
- Copyright 1995-2013 Esri
-
- Licensed 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.
-
- For additional information, contact:
- Environmental Systems Research Institute, Inc.
- Attn: Contracts Dept
- 380 New York Street
- Redlands, California, USA 92373
-
- email: contracts@esri.com
- */
-
-package com.esri.core.geometry;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import org.codehaus.jackson.JsonParser;
-import org.json.JSONException;
-
-/**
- * Provides services that operate on geometry instances.
- */
-public class GeometryEngine {
-
- private static OperatorFactoryLocal factory = OperatorFactoryLocal
- .getInstance();
-
- /**
- * Imports the MapGeometry from its JSON representation. M and Z values are
- * not imported from JSON representation.
- *
- * @param json
- * The JSON representation of the geometry (with spatial
- * reference).
- * @return The MapGeometry instance containing the imported geometry and its
- * spatial reference.
- */
- public static MapGeometry jsonToGeometry(JsonParser json) {
- MapGeometry geom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, json);
- return geom;
- }
-
- /**
- * Exports the specified geometry instance to it's JSON representation.
- *
- * @see GeometryEngine#geometryToJson(SpatialReference spatialiReference,
- * Geometry geometry)
- * @param wkid
- * The spatial reference Well Known ID to be used for the JSON
- * representation.
- * @param geometry
- * The geometry to be exported to JSON.
- * @return The JSON representation of the specified Geometry.
- */
- public static String geometryToJson(int wkid, Geometry geometry) {
- return GeometryEngine.geometryToJson(
- wkid > 0 ? SpatialReference.create(wkid) : null, geometry);
- }
-
- /**
- * Exports the specified geometry instance to it's JSON representation. M
- * and Z values are not imported from JSON representation.
- *
- * @param spatialReference
- * The spatial reference of associated object.
- * @param geometry
- * The geometry.
- * @return The JSON representation of the specified geometry.
- */
- public static String geometryToJson(SpatialReference spatialReference,
- Geometry geometry) {
- OperatorExportToJson exporter = (OperatorExportToJson) factory
- .getOperator(Operator.Type.ExportToJson);
-
- return exporter.execute(spatialReference, geometry);
- }
-
- public static String geometryToGeoJson(Geometry geometry) {
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory
- .getOperator(Operator.Type.ExportToGeoJson);
-
- return exporter.execute(geometry);
- }
-
- /**
- * Exports the specified geometry instance to its GeoJSON representation.
- *
- * @see GeometryEngine#geometryToGeoJson(SpatialReference spatialReference,
- * Geometry geometry)
- *
- * @param wkid
- * The spatial reference Well Known ID to be used for the GeoJSON representation.
- * @param geometry
- * The geometry to be exported to GeoJSON.
- * @return The GeoJSON representation of the specified geometry.
- */
- public static String geometryToGeoJson(int wkid, Geometry geometry) {
- return GeometryEngine.geometryToGeoJson(
- wkid > 0 ? SpatialReference.create(wkid) : null, geometry);
- }
-
- /**
- * Exports the specified geometry instance to it's JSON representation.
- *
- * @param spatialReference
- * The spatial reference of associated object.
- * @param geometry
- * The geometry.
- * @return The GeoJSON representation of the specified geometry.
- */
- public static String geometryToGeoJson(SpatialReference spatialReference,
- Geometry geometry) {
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory
- .getOperator(Operator.Type.ExportToGeoJson);
-
- return exporter.execute(spatialReference, geometry);
- }
-
- /**
- * Imports geometry from the ESRI shape file format.
- *
- * @param esriShapeBuffer
- * The buffer containing geometry in the ESRI shape file format.
- * @param geometryType
- * The required type of the Geometry to be imported. Use
- * Geometry.Type.Unknown if the geometry type needs to be
- * determined from the buffer content.
- * @return The geometry or null if the buffer contains null shape.
- * @throws GeometryException
- * when the geometryType is not Geometry.Type.Unknown and the
- * buffer contains geometry that cannot be converted to the
- * given geometryType. or the buffer is corrupt. Another
- * exception possible is IllegalArgumentsException.
- */
- public static Geometry geometryFromEsriShape(byte[] esriShapeBuffer,
- Geometry.Type geometryType) {
- OperatorImportFromESRIShape op = (OperatorImportFromESRIShape) factory
- .getOperator(Operator.Type.ImportFromESRIShape);
- return op
- .execute(
- ShapeImportFlags.ShapeImportNonTrusted,
- geometryType,
- ByteBuffer.wrap(esriShapeBuffer).order(
- ByteOrder.LITTLE_ENDIAN));
- }
-
- /**
- * Exports geometry to the ESRI shape file format.
- *
- * @param geometry
- * The geometry to export. (null value is not allowed)
- * @return Array containing the exported ESRI shape file.
- */
- public static byte[] geometryToEsriShape(Geometry geometry) {
- if (geometry == null)
- throw new IllegalArgumentException();
- OperatorExportToESRIShape op = (OperatorExportToESRIShape) factory
- .getOperator(Operator.Type.ExportToESRIShape);
- return op.execute(0, geometry).array();
- }
-
- /**
- * Imports a geometry from a WKT string.
- * @param wkt The string containing the geometry in WKT format.
- * @param importFlags Use the {@link WktImportFlags} interface.
- * @param geometryType The required type of the Geometry to be imported. Use Geometry.Type.Unknown if the geometry type needs to be determined from the WKT context.
- * @return The geometry.
- * @throws GeometryException when the geometryType is not Geometry.Type.Unknown and the WKT contains a geometry that cannot be converted to the given geometryType.
- * @throws IllegalArgument exception if an error is found while parsing the WKT string.
- */
- public static Geometry geometryFromWkt(String wkt, int importFlags,
- Geometry.Type geometryType) {
- OperatorImportFromWkt op = (OperatorImportFromWkt) factory
- .getOperator(Operator.Type.ImportFromWkt);
- return op.execute(importFlags, geometryType, wkt, null);
- }
-
- /**
- * Imports a geometry from a geoJson string.
- * @param geoJson The string containing the geometry in geoJson format.
- * @param importFlags Use the {@link GeoJsonImportFlags} interface.
- * @param geometryType The required type of the Geometry to be imported. Use Geometry.Type.Unknown if the geometry type needs to be determined from the geoJson context.
- * @return The geometry.
- * @throws GeometryException when the geometryType is not Geometry.Type.Unknown and the geoJson contains a geometry that cannot be converted to the given geometryType.
- * @throws IllegalArgument exception if an error is found while parsing the geoJson string.
- */
- public static MapGeometry geometryFromGeoJson(String geoJson,
- int importFlags, Geometry.Type geometryType) throws JSONException {
- OperatorImportFromGeoJson op = (OperatorImportFromGeoJson) factory
- .getOperator(Operator.Type.ImportFromGeoJson);
- return op.execute(importFlags, geometryType, geoJson, null);
- }
-
- /**
- * Exports a geometry to a string in WKT format.
- * @param geometry The geometry to export. (null value is not allowed)
- * @param exportFlags Use the {@link WktExportFlags} interface.
- * @return A String containing the exported geometry in WKT format.
- */
- public static String geometryToWkt(Geometry geometry, int exportFlags) {
- OperatorExportToWkt op = (OperatorExportToWkt) factory
- .getOperator(Operator.Type.ExportToWkt);
- return op.execute(exportFlags, geometry, null);
- }
-
- /**
- * Constructs a new geometry by union an array of geometries. All inputs
- * must be of the same type of geometries and share one spatial reference.
- *
- * @param geometries
- * The geometries to union.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return The geometry object representing the resultant union.
- */
- public static Geometry union(Geometry[] geometries,
- SpatialReference spatialReference) {
- OperatorUnion op = (OperatorUnion) factory
- .getOperator(Operator.Type.Union);
-
- SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(
- geometries);
- GeometryCursor result = op.execute(inputGeometries, spatialReference,
- null);
- return result.next();
- }
-
- // TODO Remove this method from geometry engine
- /**
- * constructs the set-theoretic difference between an array of geometries
- * and another geometry. The dimension of the input geometry has to be equal
- * to or greater than that of any element in the array of "geometries".
- *
- * @param inputGeometries
- * an array of geometry objects being subtracted
- * @param subtractor
- * geometry object to subtract from
- * @return any array of geometry objects showing the difference
- * */
- static Geometry[] difference(Geometry[] inputGeometries,
- Geometry subtractor, SpatialReference spatialReference) {
- OperatorDifference op = (OperatorDifference) factory
- .getOperator(Operator.Type.Difference);
- SimpleGeometryCursor inputGeometriesCursor = new SimpleGeometryCursor(
- inputGeometries);
- SimpleGeometryCursor subtractorCursor = new SimpleGeometryCursor(
- subtractor);
- GeometryCursor result = op.execute(inputGeometriesCursor,
- subtractorCursor, spatialReference, null);
-
- ArrayList resultGeoms = new ArrayList();
- Geometry g;
- while ((g = result.next()) != null) {
- resultGeoms.add(g);
- }
- Geometry[] resultarr = resultGeoms.toArray(new Geometry[0]);
- return resultarr;
- }
-
- /**
- * Creates the difference of two geometries. The dimension of geometry2 has
- * to be equal to or greater than that of geometry1.
- *
- * @param geometry1
- * The geometry being subtracted.
- * @param substractor
- * The geometry object to subtract from.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return The geometry of the differences.
- */
- public static Geometry difference(Geometry geometry1, Geometry substractor,
- SpatialReference spatialReference) {
- OperatorDifference op = (OperatorDifference) factory
- .getOperator(Operator.Type.Difference);
- Geometry result = op.execute(geometry1, substractor, spatialReference,
- null);
- return result;
- }
-
- /**
- * Creates the symmetric difference of two geometries.
- *
- * @param leftGeometry
- * is one of the Geometry instances in the XOR operation.
- * @param rightGeometry
- * is one of the Geometry instances in the XOR operation.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return Returns the result of the symmetric difference.
- */
- public static Geometry symmetricDifference(Geometry leftGeometry,
- Geometry rightGeometry, SpatialReference spatialReference) {
- OperatorSymmetricDifference op = (OperatorSymmetricDifference) factory
- .getOperator(Operator.Type.SymmetricDifference);
- Geometry result = op.execute(leftGeometry, rightGeometry,
- spatialReference, null);
- return result;
- }
-
- /**
- * Indicates if two geometries are equal.
- *
- * @param geometry1
- * Geometry.
- * @param geometry2
- * Geometry.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return TRUE if both geometry objects are equal.
- */
- public static boolean equals(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorEquals op = (OperatorEquals) factory
- .getOperator(Operator.Type.Equals);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- null);
- return result;
- }
-
- public static boolean disjoint(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorDisjoint op = (OperatorDisjoint) factory
- .getOperator(Operator.Type.Disjoint);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- null);
- return result;
- }
-
- /**
- * Constructs the set-theoretic intersection between an array of geometries
- * and another geometry.
- *
- * @param inputGeometries
- * An array of geometry objects.
- * @param geometry
- * The geometry object.
- * @return Any array of geometry objects showing the intersection.
- */
- static Geometry[] intersect(Geometry[] inputGeometries, Geometry geometry,
- SpatialReference spatialReference) {
- OperatorIntersection op = (OperatorIntersection) factory
- .getOperator(Operator.Type.Intersection);
- SimpleGeometryCursor inputGeometriesCursor = new SimpleGeometryCursor(
- inputGeometries);
- SimpleGeometryCursor intersectorCursor = new SimpleGeometryCursor(
- geometry);
- GeometryCursor result = op.execute(inputGeometriesCursor,
- intersectorCursor, spatialReference, null);
-
- ArrayList resultGeoms = new ArrayList();
- Geometry g;
- while ((g = result.next()) != null) {
- resultGeoms.add(g);
- }
-
- Geometry[] resultarr = resultGeoms.toArray(new Geometry[0]);
- return resultarr;
- }
-
- /**
- * Creates a geometry through intersection between two geometries.
- *
- * @param geometry1
- * The first geometry.
- * @param intersector
- * The geometry to intersect the first geometry.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return The geometry created through intersection.
- */
- public static Geometry intersect(Geometry geometry1, Geometry intersector,
- SpatialReference spatialReference) {
- OperatorIntersection op = (OperatorIntersection) factory
- .getOperator(Operator.Type.Intersection);
- Geometry result = op.execute(geometry1, intersector, spatialReference,
- null);
- return result;
- }
-
- /**
- * Indicates if one geometry is within another geometry.
- *
- * @param geometry1
- * The base geometry that is tested for within relationship to
- * the other geometry.
- * @param geometry2
- * The comparison geometry that is tested for the contains
- * relationship to the other geometry.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return TRUE if the first geometry is within the other geometry.
- */
- public static boolean within(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorWithin op = (OperatorWithin) factory
- .getOperator(Operator.Type.Within);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- null);
- return result;
- }
-
- /**
- * Indicates if one geometry contains another geometry.
- *
- * @param geometry1
- * The geometry that is tested for the contains relationship to
- * the other geometry..
- * @param geometry2
- * The geometry that is tested for within relationship to the
- * other geometry.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return TRUE if geometry1 contains geometry2.
- */
- public static boolean contains(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorContains op = (OperatorContains) factory
- .getOperator(Operator.Type.Contains);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- null);
- return result;
- }
-
- /**
- * Indicates if one geometry crosses another geometry.
- *
- * @param geometry1
- * The geometry to cross.
- * @param geometry2
- * The geometry being crossed.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return TRUE if geometry1 crosses geometry2.
- */
- public static boolean crosses(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorCrosses op = (OperatorCrosses) factory
- .getOperator(Operator.Type.Crosses);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- null);
- return result;
- }
-
- /**
- * Indicates if one geometry touches another geometry.
- *
- * @param geometry1
- * The geometry to touch.
- * @param geometry2
- * The geometry to be touched.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return TRUE if geometry1 touches geometry2.
- */
- public static boolean touches(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorTouches op = (OperatorTouches) factory
- .getOperator(Operator.Type.Touches);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- null);
- return result;
- }
-
- /**
- * Indicates if one geometry overlaps another geometry.
- *
- * @param geometry1
- * The geometry to overlap.
- * @param geometry2
- * The geometry to be overlapped.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return TRUE if geometry1 overlaps geometry2.
- */
- public static boolean overlaps(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorOverlaps op = (OperatorOverlaps) factory
- .getOperator(Operator.Type.Overlaps);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- null);
- return result;
- }
-
- /**
- * Indicates if the given relation holds for the two geometries.
- *
- * @param geometry1
- * The first geometry for the relation.
- * @param geometry2
- * The second geometry for the relation.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @param relation
- * The DE-9IM relation.
- * @return TRUE if the given relation holds between geometry1 and geometry2.
- */
- public static boolean relate(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference, String relation) {
- OperatorRelate op = (OperatorRelate) factory
- .getOperator(Operator.Type.Relate);
- boolean result = op.execute(geometry1, geometry2, spatialReference,
- relation, null);
- return result;
- }
-
- /**
- * Calculates the 2D planar distance between two geometries.
- *
- * @param geometry1
- * Geometry.
- * @param geometry2
- * Geometry.
- * @param spatialReference
- * The spatial reference of the geometries. This parameter is not
- * used and can be null.
- * @return The distance between the two geometries.
- */
- public static double distance(Geometry geometry1, Geometry geometry2,
- SpatialReference spatialReference) {
- OperatorDistance op = (OperatorDistance) factory
- .getOperator(Operator.Type.Distance);
- double result = op.execute(geometry1, geometry2, null);
- return result;
- }
-
- /**
- * Calculates the clipped geometry from a target geometry using an envelope.
- *
- * @param geometry
- * The geometry to be clipped.
- * @param envelope
- * The envelope used to clip.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return The geometry created by clipping.
- */
- public static Geometry clip(Geometry geometry, Envelope envelope,
- SpatialReference spatialReference) {
- OperatorClip op = (OperatorClip) factory
- .getOperator(Operator.Type.Clip);
- Geometry result = op.execute(geometry, Envelope2D.construct(
- envelope.getXMin(), envelope.getYMin(), envelope.getXMax(),
- envelope.getYMax()), spatialReference, null);
- return result;
- }
-
- /**
- * Calculates the cut geometry from a target geometry using a polyline. For
- * Polylines, all left cuts will be grouped together in the first Geometry,
- * Right cuts and coincident cuts are grouped in the second Geometry, and
- * each undefined cut, along with any uncut parts, are output as separate
- * Polylines. For Polygons, all left cuts are grouped in the first Polygon,
- * all right cuts are in the second Polygon, and each undefined cut, along
- * with any left-over parts after cutting, are output as a separate Polygon.
- * If there were no cuts then the array will be empty. An undefined cut will
- * only be produced if a left cut or right cut was produced, and there was a
- * part left over after cutting or a cut is bounded to the left and right of
- * the cutter.
- *
- * @param cuttee
- * The geometry to be cut.
- * @param cutter
- * The polyline to cut the geometry.
- * @param spatialReference
- * The spatial reference of the geometries.
- * @return An array of geometries created from cutting.
- */
- public static Geometry[] cut(Geometry cuttee, Polyline cutter,
- SpatialReference spatialReference) {
- if (cuttee == null || cutter == null)
- return null;
-
- OperatorCut op = (OperatorCut) factory.getOperator(Operator.Type.Cut);
- GeometryCursor cursor = op.execute(true, cuttee, cutter,
- spatialReference, null);
- ArrayList cutsList = new ArrayList();
-
- Geometry geometry;
- while ((geometry = cursor.next()) != null) {
- if (!geometry.isEmpty()) {
- cutsList.add(geometry);
- }
- }
-
- return cutsList.toArray(new Geometry[0]);
- }
-
- /**
- * Calculates a buffer polygon for each geometry at each of the
- * corresponding specified distances. It is assumed that all geometries have
- * the same spatial reference. There is an option to union the
- * returned geometries.
- * @param geometries An array of geometries to be buffered.
- * @param spatialReference The spatial reference of the geometries.
- * @param distances The corresponding distances for the input geometries to be buffered.
- * @param toUnionResults TRUE if all geometries buffered at a given distance are to be unioned into a single polygon.
- * @return The buffer of the geometries.
- * */
- public static Polygon[] buffer(Geometry[] geometries,
- SpatialReference spatialReference, double[] distances,
- boolean toUnionResults) {
- // initially assume distances are in unit of spatial reference
- double[] bufferDistances = distances;
-
- OperatorBuffer op = (OperatorBuffer) factory
- .getOperator(Operator.Type.Buffer);
-
- if (toUnionResults) {
- SimpleGeometryCursor inputGeometriesCursor = new SimpleGeometryCursor(
- geometries);
- GeometryCursor result = op.execute(inputGeometriesCursor,
- spatialReference, bufferDistances, toUnionResults, null);
-
- ArrayList resultGeoms = new ArrayList();
- Geometry g;
- while ((g = result.next()) != null) {
- resultGeoms.add((Polygon) g);
- }
- Polygon[] buffers = resultGeoms.toArray(new Polygon[0]);
- return buffers;
- } else {
- Polygon[] buffers = new Polygon[geometries.length];
- for (int i = 0; i < geometries.length; i++) {
- buffers[i] = (Polygon) op.execute(geometries[i],
- spatialReference, bufferDistances[i], null);
- }
- return buffers;
- }
- }
-
- /**
- * Calculates a buffer polygon of the geometry as specified by the
- * distance input. The buffer is implemented in the xy-plane.
- * @param geometry Geometry to be buffered.
- * @param spatialReference The spatial reference of the geometry.
- * @param distance The specified distance for buffer. Same units as the spatial reference.
- * @return The buffer polygon at the specified distances.
- * */
- public static Polygon buffer(Geometry geometry,
- SpatialReference spatialReference, double distance) {
- double bufferDistance = distance;
-
- OperatorBuffer op = (OperatorBuffer) factory
- .getOperator(Operator.Type.Buffer);
- Geometry result = op.execute(geometry, spatialReference,
- bufferDistance, null);
- return (Polygon) result;
- }
-
- /**
- * Calculates the convex hull geometry.
- *
- * @param geometry The input geometry.
- * @return Returns the convex hull.
- *
- * For a Point - returns the same point. For an Envelope -
- * returns the same envelope. For a MultiPoint - If the point
- * count is one, returns the same multipoint. If the point count
- * is two, returns a polyline of the points. Otherwise computes
- * and returns the convex hull polygon. For a Segment - returns a
- * polyline consisting of the segment. For a Polyline - If
- * consists of only one segment, returns the same polyline.
- * Otherwise computes and returns the convex hull polygon. For a
- * Polygon - If more than one path, or if the path isn't already
- * convex, computes and returns the convex hull polygon.
- * Otherwise returns the same polygon.
- */
- public static Geometry convexHull(Geometry geometry) {
- OperatorConvexHull op = (OperatorConvexHull) factory
- .getOperator(Operator.Type.ConvexHull);
- return op.execute(geometry, null);
- }
-
- /**
- * Calculates the convex hull.
- *
- * @param geometries
- * The input geometry array.
- * @param b_merge
- * Put true if you want the convex hull of all the geometries in
- * the array combined. Put false if you want the convex hull of
- * each geometry in the array individually.
- * @return Returns an array of convex hulls. If b_merge is true, the result
- * will be a one element array consisting of the merged convex hull.
- */
- public static Geometry[] convexHull(Geometry[] geometries, boolean b_merge) {
- OperatorConvexHull op = (OperatorConvexHull) factory
- .getOperator(Operator.Type.ConvexHull);
- SimpleGeometryCursor simple_cursor = new SimpleGeometryCursor(
- geometries);
- GeometryCursor cursor = op.execute(simple_cursor, b_merge, null);
-
- ArrayList resultGeoms = new ArrayList();
- Geometry g;
- while ((g = cursor.next()) != null) {
- resultGeoms.add(g);
- }
-
- Geometry[] output = new Geometry[resultGeoms.size()];
-
- for (int i = 0; i < resultGeoms.size(); i++)
- output[i] = resultGeoms.get(i);
-
- return output;
- }
-
- /**
- * Finds the coordinate of the geometry which is closest to the specified
- * point.
- *
- * @param inputPoint
- * The point to find the nearest coordinate in the geometry for.
- * @param geometry
- * The geometry to consider.
- * @return Proximity2DResult containing the nearest coordinate.
- * */
- public static Proximity2DResult getNearestCoordinate(Geometry geometry,
- Point inputPoint, boolean bTestPolygonInterior) {
-
- OperatorProximity2D proximity = (OperatorProximity2D) factory
- .getOperator(com.esri.core.geometry.Operator.Type.Proximity2D);
- Proximity2DResult result = proximity.getNearestCoordinate(geometry,
- inputPoint, bTestPolygonInterior);
- return result;
- }
-
- /**
- * Finds nearest vertex on the geometry which is closed to the specified
- * point.
- *
- * @param inputPoint
- * The point to find the nearest vertex of the geometry for.
- * @param geometry
- * The geometry to consider.
- * @return Proximity2DResult containing the nearest vertex.
- * */
- public static Proximity2DResult getNearestVertex(Geometry geometry,
- Point inputPoint) {
- OperatorProximity2D proximity = (OperatorProximity2D) factory
- .getOperator(com.esri.core.geometry.Operator.Type.Proximity2D);
- Proximity2DResult result = proximity.getNearestVertex(geometry,
- inputPoint);
- return result;
- }
-
- /**
- * Finds all vertices in the given distance from the specified point, sorted
- * from the closest to the furthest.
- *
- * @param inputPoint
- * The point to start from.
- * @param geometry
- * The geometry to consider.
- * @param searchRadius
- * The search radius.
- * @param maxVertexCountToReturn
- * The maximum number number of vertices to return.
- * @return Proximity2DResult containing the array of nearest vertices.
- * */
- public static Proximity2DResult[] getNearestVertices(Geometry geometry,
- Point inputPoint, double searchRadius, int maxVertexCountToReturn) {
- OperatorProximity2D proximity = (OperatorProximity2D) factory
- .getOperator(com.esri.core.geometry.Operator.Type.Proximity2D);
-
- Proximity2DResult[] results = proximity.getNearestVertices(geometry,
- inputPoint, searchRadius, maxVertexCountToReturn);
-
- return results;
- }
-
- /**
- * Performs the simplify operation on the geometry.
- *
- * @param geometry
- * The geometry to be simplified.
- * @param spatialReference
- * The spatial reference of the geometry to be simplified.
- * @return The simplified geometry.
- */
- public static Geometry simplify(Geometry geometry,
- SpatialReference spatialReference) {
- OperatorSimplify op = (OperatorSimplify) factory
- .getOperator(Operator.Type.Simplify);
- Geometry result = op.execute(geometry, spatialReference, false, null);
- return result;
- }
-
- /**
- * Checks if the Geometry is simple.
- *
- * @param geometry
- * The geometry to be checked.
- * @param spatialReference
- * The spatial reference of the geometry.
- * @return TRUE if the geometry is simple.
- */
- static boolean isSimple(Geometry geometry, SpatialReference spatialReference) {
- OperatorSimplify op = (OperatorSimplify) factory
- .getOperator(Operator.Type.Simplify);
- boolean result = op.isSimpleAsFeature(geometry, spatialReference, null);
- return result;
- }
-
- /**
- * A geodesic distance is the shortest distance between any two points on the earth's surface when the earth's
- * surface is approximated by a spheroid. The function returns the shortest distance between two points on the
- * WGS84 spheroid.
- * @param ptFrom The "from" point: long, lat in degrees.
- * @param ptTo The "to" point: long, lat in degrees.
- * @return The geodesic distance between two points in meters.
- */
- public static double geodesicDistanceOnWGS84(Point ptFrom, Point ptTo) {
- return SpatialReferenceImpl.geodesicDistanceOnWGS84Impl(ptFrom, ptTo);
- }
-}
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+
+import com.fasterxml.jackson.core.JsonParser;
+
+/**
+ * Provides services that operate on geometry instances. The methods of GeometryEngine class call corresponding OperatorXXX classes.
+ * Consider using OperatorXXX classes directly as they often provide more functionality and better performance. For example, some Operators accept
+ * GeometryCursor class that could be implemented to wrap a feature cursor and make it feed geometries directly into an Operator.
+ * Also, some operators provide a way to accelerate an operation by using Operator.accelerateGeometry method.
+ */
+public class GeometryEngine {
+
+ private static OperatorFactoryLocal factory = OperatorFactoryLocal
+ .getInstance();
+
+
+ /**
+ * Imports the MapGeometry from its JSON representation. M and Z values are
+ * not imported from JSON representation.
+ *
+ * See OperatorImportFromJson.
+ *
+ * @param json
+ * The JSON representation of the geometry (with spatial
+ * reference).
+ * @return The MapGeometry instance containing the imported geometry and its
+ * spatial reference.
+ */
+ public static MapGeometry jsonToGeometry(JsonParser json) {
+ MapGeometry geom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, new JsonParserReader(json));
+ return geom;
+ }
+
+ /**
+ * Imports the MapGeometry from its JSON representation. M and Z values are
+ * not imported from JSON representation.
+ *
+ * See OperatorImportFromJson.
+ *
+ * @param json
+ * The JSON representation of the geometry (with spatial
+ * reference).
+ * @return The MapGeometry instance containing the imported geometry and its
+ * spatial reference.
+ */
+ public static MapGeometry jsonToGeometry(JsonReader json) {
+ MapGeometry geom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, json);
+ return geom;
+ }
+
+ /**
+ * Imports the MapGeometry from its JSON representation. M and Z values are
+ * not imported from JSON representation.
+ *
+ * See OperatorImportFromJson.
+ *
+ * @param json
+ * The JSON representation of the geometry (with spatial
+ * reference).
+ * @return The MapGeometry instance containing the imported geometry and its
+ * spatial reference.
+ */
+ public static MapGeometry jsonToGeometry(String json) {
+ MapGeometry geom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, json);
+ return geom;
+ }
+
+ /**
+ * Exports the specified geometry instance to it's JSON representation.
+ *
+ * See OperatorExportToJson.
+ *
+ * @see GeometryEngine#geometryToJson(SpatialReference spatialiReference,
+ * Geometry geometry)
+ * @param wkid
+ * The spatial reference Well Known ID to be used for the JSON
+ * representation.
+ * @param geometry
+ * The geometry to be exported to JSON.
+ * @return The JSON representation of the specified Geometry.
+ */
+ public static String geometryToJson(int wkid, Geometry geometry) {
+ return GeometryEngine.geometryToJson(
+ wkid > 0 ? SpatialReference.create(wkid) : null, geometry);
+ }
+
+ /**
+ * Exports the specified geometry instance to it's JSON representation. M
+ * and Z values are not imported from JSON representation.
+ *
+ * See OperatorExportToJson.
+ *
+ * @param spatialReference
+ * The spatial reference of associated object.
+ * @param geometry
+ * The geometry.
+ * @return The JSON representation of the specified geometry.
+ */
+ public static String geometryToJson(SpatialReference spatialReference,
+ Geometry geometry) {
+ OperatorExportToJson exporter = (OperatorExportToJson) factory
+ .getOperator(Operator.Type.ExportToJson);
+
+ return exporter.execute(spatialReference, geometry);
+ }
+
+ public static String geometryToGeoJson(Geometry geometry) {
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory
+ .getOperator(Operator.Type.ExportToGeoJson);
+
+ return exporter.execute(geometry);
+ }
+
+ /**
+ * Imports the MapGeometry from its JSON representation. M and Z values are
+ * not imported from JSON representation.
+ *
+ * See OperatorImportFromJson.
+ *
+ * @param json
+ * The JSON representation of the geometry (with spatial
+ * reference).
+ * @return The MapGeometry instance containing the imported geometry and its
+ * spatial reference.
+ */
+ public static MapGeometry geoJsonToGeometry(String json, int importFlags, Geometry.Type type) {
+ MapGeometry geom = OperatorImportFromGeoJson.local().execute(importFlags, type, json, null);
+ return geom;
+ }
+
+ /**
+ * Exports the specified geometry instance to its GeoJSON representation.
+ *
+ * See OperatorExportToGeoJson.
+ *
+ * @see GeometryEngine#geometryToGeoJson(SpatialReference spatialReference,
+ * Geometry geometry)
+ *
+ * @param wkid
+ * The spatial reference Well Known ID to be used for the GeoJSON
+ * representation.
+ * @param geometry
+ * The geometry to be exported to GeoJSON.
+ * @return The GeoJSON representation of the specified geometry.
+ */
+ public static String geometryToGeoJson(int wkid, Geometry geometry) {
+ return GeometryEngine.geometryToGeoJson(wkid > 0 ? SpatialReference.create(wkid) : null, geometry);
+ }
+
+ /**
+ * Exports the specified geometry instance to it's JSON representation.
+ *
+ * See OperatorImportFromGeoJson.
+ *
+ * @param spatialReference
+ * The spatial reference of associated object.
+ * @param geometry
+ * The geometry.
+ * @return The GeoJSON representation of the specified geometry.
+ */
+ public static String geometryToGeoJson(SpatialReference spatialReference, Geometry geometry) {
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+
+ return exporter.execute(spatialReference, geometry);
+ }
+
+ /**
+ * Imports geometry from the ESRI shape file format.
+ *
+ * See OperatorImportFromESRIShape.
+ *
+ * @param esriShapeBuffer
+ * The buffer containing geometry in the ESRI shape file format.
+ * @param geometryType
+ * The required type of the Geometry to be imported. Use
+ * Geometry.Type.Unknown if the geometry type needs to be
+ * determined from the buffer content.
+ * @return The geometry or null if the buffer contains null shape.
+ * @throws GeometryException
+ * when the geometryType is not Geometry.Type.Unknown and the
+ * buffer contains geometry that cannot be converted to the
+ * given geometryType. or the buffer is corrupt. Another
+ * exception possible is IllegalArgumentsException.
+ */
+ public static Geometry geometryFromEsriShape(byte[] esriShapeBuffer,
+ Geometry.Type geometryType) {
+ OperatorImportFromESRIShape op = (OperatorImportFromESRIShape) factory
+ .getOperator(Operator.Type.ImportFromESRIShape);
+ return op
+ .execute(
+ ShapeImportFlags.ShapeImportNonTrusted,
+ geometryType,
+ ByteBuffer.wrap(esriShapeBuffer).order(
+ ByteOrder.LITTLE_ENDIAN));
+ }
+
+ /**
+ * Exports geometry to the ESRI shape file format.
+ *
+ * See OperatorExportToESRIShape.
+ *
+ * @param geometry
+ * The geometry to export. (null value is not allowed)
+ * @return Array containing the exported ESRI shape file.
+ */
+ public static byte[] geometryToEsriShape(Geometry geometry) {
+ if (geometry == null)
+ throw new IllegalArgumentException();
+ OperatorExportToESRIShape op = (OperatorExportToESRIShape) factory
+ .getOperator(Operator.Type.ExportToESRIShape);
+ return op.execute(0, geometry).array();
+ }
+
+ /**
+ * Imports a geometry from a WKT string.
+ *
+ * See OperatorImportFromWkt.
+ *
+ * @param wkt The string containing the geometry in WKT format.
+ * @param importFlags Use the {@link WktImportFlags} interface.
+ * @param geometryType The required type of the Geometry to be imported. Use Geometry.Type.Unknown if the geometry type needs to be determined from the WKT context.
+ * @return The geometry.
+ * @throws GeometryException when the geometryType is not Geometry.Type.Unknown and the WKT contains a geometry that cannot be converted to the given geometryType.
+ * @throws IllegalArgumentException if an error is found while parsing the WKT string.
+ */
+ public static Geometry geometryFromWkt(String wkt, int importFlags,
+ Geometry.Type geometryType) {
+ OperatorImportFromWkt op = (OperatorImportFromWkt) factory
+ .getOperator(Operator.Type.ImportFromWkt);
+ return op.execute(importFlags, geometryType, wkt, null);
+ }
+
+ /**
+ * Exports a geometry to a string in WKT format.
+ *
+ * See OperatorExportToWkt.
+ *
+ * @param geometry The geometry to export. (null value is not allowed)
+ * @param exportFlags Use the {@link WktExportFlags} interface.
+ * @return A String containing the exported geometry in WKT format.
+ */
+ public static String geometryToWkt(Geometry geometry, int exportFlags) {
+ OperatorExportToWkt op = (OperatorExportToWkt) factory
+ .getOperator(Operator.Type.ExportToWkt);
+ return op.execute(exportFlags, geometry, null);
+ }
+
+ /**
+ * Constructs a new geometry by union an array of geometries. All inputs
+ * must be of the same type of geometries and share one spatial reference.
+ *
+ * See OperatorUnion.
+ *
+ * @param geometries
+ * The geometries to union.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return The geometry object representing the resultant union.
+ */
+ public static Geometry union(Geometry[] geometries,
+ SpatialReference spatialReference) {
+ OperatorUnion op = (OperatorUnion) factory
+ .getOperator(Operator.Type.Union);
+
+ SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(
+ geometries);
+ GeometryCursor result = op.execute(inputGeometries, spatialReference,
+ null);
+ return result.next();
+ }
+
+ /**
+ * Creates the difference of two geometries. The dimension of geometry2 has
+ * to be equal to or greater than that of geometry1.
+ *
+ * See OperatorDifference.
+ *
+ * @param geometry1
+ * The geometry being subtracted.
+ * @param substractor
+ * The geometry object to subtract from.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return The geometry of the differences.
+ */
+ public static Geometry difference(Geometry geometry1, Geometry substractor,
+ SpatialReference spatialReference) {
+ OperatorDifference op = (OperatorDifference) factory
+ .getOperator(Operator.Type.Difference);
+ Geometry result = op.execute(geometry1, substractor, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Creates the symmetric difference of two geometries.
+ *
+ * See OperatorSymmetricDifference.
+ *
+ * @param leftGeometry
+ * is one of the Geometry instances in the XOR operation.
+ * @param rightGeometry
+ * is one of the Geometry instances in the XOR operation.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return Returns the result of the symmetric difference.
+ */
+ public static Geometry symmetricDifference(Geometry leftGeometry,
+ Geometry rightGeometry, SpatialReference spatialReference) {
+ OperatorSymmetricDifference op = (OperatorSymmetricDifference) factory
+ .getOperator(Operator.Type.SymmetricDifference);
+ Geometry result = op.execute(leftGeometry, rightGeometry,
+ spatialReference, null);
+ return result;
+ }
+
+ /**
+ * Indicates if two geometries are equal.
+ *
+ * See OperatorEquals.
+ *
+ * @param geometry1
+ * Geometry.
+ * @param geometry2
+ * Geometry.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return TRUE if both geometry objects are equal.
+ */
+ public static boolean equals(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorEquals op = (OperatorEquals) factory
+ .getOperator(Operator.Type.Equals);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * See OperatorDisjoint.
+ *
+ */
+ public static boolean disjoint(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorDisjoint op = (OperatorDisjoint) factory
+ .getOperator(Operator.Type.Disjoint);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Constructs the set-theoretic intersection between an array of geometries
+ * and another geometry.
+ *
+ * See OperatorIntersection (also for dimension specific intersection).
+ *
+ * @param inputGeometries
+ * An array of geometry objects.
+ * @param geometry
+ * The geometry object.
+ * @return Any array of geometry objects showing the intersection.
+ */
+ static Geometry[] intersect(Geometry[] inputGeometries, Geometry geometry,
+ SpatialReference spatialReference) {
+ OperatorIntersection op = (OperatorIntersection) factory
+ .getOperator(Operator.Type.Intersection);
+ SimpleGeometryCursor inputGeometriesCursor = new SimpleGeometryCursor(
+ inputGeometries);
+ SimpleGeometryCursor intersectorCursor = new SimpleGeometryCursor(
+ geometry);
+ GeometryCursor result = op.execute(inputGeometriesCursor,
+ intersectorCursor, spatialReference, null);
+
+ ArrayList resultGeoms = new ArrayList();
+ Geometry g;
+ while ((g = result.next()) != null) {
+ resultGeoms.add(g);
+ }
+
+ Geometry[] resultarr = resultGeoms.toArray(new Geometry[0]);
+ return resultarr;
+ }
+
+ /**
+ * Creates a geometry through intersection between two geometries.
+ *
+ * See OperatorIntersection.
+ *
+ * @param geometry1
+ * The first geometry.
+ * @param intersector
+ * The geometry to intersect the first geometry.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return The geometry created through intersection.
+ */
+ public static Geometry intersect(Geometry geometry1, Geometry intersector,
+ SpatialReference spatialReference) {
+ OperatorIntersection op = (OperatorIntersection) factory
+ .getOperator(Operator.Type.Intersection);
+ Geometry result = op.execute(geometry1, intersector, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Indicates if one geometry is within another geometry.
+ *
+ * See OperatorWithin.
+ *
+ * @param geometry1
+ * The base geometry that is tested for within relationship to
+ * the other geometry.
+ * @param geometry2
+ * The comparison geometry that is tested for the contains
+ * relationship to the other geometry.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return TRUE if the first geometry is within the other geometry.
+ */
+ public static boolean within(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorWithin op = (OperatorWithin) factory
+ .getOperator(Operator.Type.Within);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Indicates if one geometry contains another geometry.
+ *
+ * See OperatorContains.
+ *
+ * @param geometry1
+ * The geometry that is tested for the contains relationship to
+ * the other geometry..
+ * @param geometry2
+ * The geometry that is tested for within relationship to the
+ * other geometry.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return TRUE if geometry1 contains geometry2.
+ */
+ public static boolean contains(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorContains op = (OperatorContains) factory
+ .getOperator(Operator.Type.Contains);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Indicates if one geometry crosses another geometry.
+ *
+ * See OperatorCrosses.
+ *
+ * @param geometry1
+ * The geometry to cross.
+ * @param geometry2
+ * The geometry being crossed.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return TRUE if geometry1 crosses geometry2.
+ */
+ public static boolean crosses(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorCrosses op = (OperatorCrosses) factory
+ .getOperator(Operator.Type.Crosses);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Indicates if one geometry touches another geometry.
+ *
+ * See OperatorTouches.
+ *
+ * @param geometry1
+ * The geometry to touch.
+ * @param geometry2
+ * The geometry to be touched.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return TRUE if geometry1 touches geometry2.
+ */
+ public static boolean touches(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorTouches op = (OperatorTouches) factory
+ .getOperator(Operator.Type.Touches);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Indicates if one geometry overlaps another geometry.
+ *
+ * See OperatorOverlaps.
+ *
+ * @param geometry1
+ * The geometry to overlap.
+ * @param geometry2
+ * The geometry to be overlapped.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return TRUE if geometry1 overlaps geometry2.
+ */
+ public static boolean overlaps(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorOverlaps op = (OperatorOverlaps) factory
+ .getOperator(Operator.Type.Overlaps);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ null);
+ return result;
+ }
+
+ /**
+ * Indicates if the given relation holds for the two geometries.
+ *
+ * See OperatorRelate.
+ *
+ * @param geometry1
+ * The first geometry for the relation.
+ * @param geometry2
+ * The second geometry for the relation.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @param relation
+ * The DE-9IM relation.
+ * @return TRUE if the given relation holds between geometry1 and geometry2.
+ */
+ public static boolean relate(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference, String relation) {
+ OperatorRelate op = (OperatorRelate) factory
+ .getOperator(Operator.Type.Relate);
+ boolean result = op.execute(geometry1, geometry2, spatialReference,
+ relation, null);
+ return result;
+ }
+
+ /**
+ * Calculates the 2D planar distance between two geometries.
+ *
+ * See OperatorDistance.
+ *
+ * @param geometry1
+ * Geometry.
+ * @param geometry2
+ * Geometry.
+ * @param spatialReference
+ * The spatial reference of the geometries. This parameter is not
+ * used and can be null.
+ * @return The distance between the two geometries.
+ */
+ public static double distance(Geometry geometry1, Geometry geometry2,
+ SpatialReference spatialReference) {
+ OperatorDistance op = (OperatorDistance) factory
+ .getOperator(Operator.Type.Distance);
+ double result = op.execute(geometry1, geometry2, null);
+ return result;
+ }
+
+ /**
+ * Calculates the clipped geometry from a target geometry using an envelope.
+ *
+ * See OperatorClip.
+ *
+ * @param geometry
+ * The geometry to be clipped.
+ * @param envelope
+ * The envelope used to clip.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return The geometry created by clipping.
+ */
+ public static Geometry clip(Geometry geometry, Envelope envelope,
+ SpatialReference spatialReference) {
+ OperatorClip op = (OperatorClip) factory
+ .getOperator(Operator.Type.Clip);
+ Geometry result = op.execute(geometry, Envelope2D.construct(
+ envelope.getXMin(), envelope.getYMin(), envelope.getXMax(),
+ envelope.getYMax()), spatialReference, null);
+ return result;
+ }
+
+ /**
+ * Calculates the cut geometry from a target geometry using a polyline. For
+ * Polylines, all left cuts will be grouped together in the first Geometry,
+ * Right cuts and coincident cuts are grouped in the second Geometry, and
+ * each undefined cut, along with any uncut parts, are output as separate
+ * Polylines. For Polygons, all left cuts are grouped in the first Polygon,
+ * all right cuts are in the second Polygon, and each undefined cut, along
+ * with any left-over parts after cutting, are output as a separate Polygon.
+ * If there were no cuts then the array will be empty. An undefined cut will
+ * only be produced if a left cut or right cut was produced, and there was a
+ * part left over after cutting or a cut is bounded to the left and right of
+ * the cutter.
+ *
+ * See OperatorCut.
+ *
+ * @param cuttee
+ * The geometry to be cut.
+ * @param cutter
+ * The polyline to cut the geometry.
+ * @param spatialReference
+ * The spatial reference of the geometries.
+ * @return An array of geometries created from cutting.
+ */
+ public static Geometry[] cut(Geometry cuttee, Polyline cutter,
+ SpatialReference spatialReference) {
+ if (cuttee == null || cutter == null)
+ return null;
+
+ OperatorCut op = (OperatorCut) factory.getOperator(Operator.Type.Cut);
+ GeometryCursor cursor = op.execute(true, cuttee, cutter,
+ spatialReference, null);
+ ArrayList cutsList = new ArrayList();
+
+ Geometry geometry;
+ while ((geometry = cursor.next()) != null) {
+ if (!geometry.isEmpty()) {
+ cutsList.add(geometry);
+ }
+ }
+
+ return cutsList.toArray(new Geometry[0]);
+ }
+ /**
+ * Calculates a buffer polygon for each geometry at each of the
+ * corresponding specified distances. It is assumed that all geometries have
+ * the same spatial reference. There is an option to union the
+ * returned geometries.
+ *
+ * See OperatorBuffer.
+ *
+ * @param geometries An array of geometries to be buffered.
+ * @param spatialReference The spatial reference of the geometries.
+ * @param distances The corresponding distances for the input geometries to be buffered.
+ * @param toUnionResults TRUE if all geometries buffered at a given distance are to be unioned into a single polygon.
+ * @return The buffer of the geometries.
+ */
+ public static Polygon[] buffer(Geometry[] geometries,
+ SpatialReference spatialReference, double[] distances,
+ boolean toUnionResults) {
+ // initially assume distances are in unit of spatial reference
+ double[] bufferDistances = distances;
+
+ OperatorBuffer op = (OperatorBuffer) factory
+ .getOperator(Operator.Type.Buffer);
+
+ if (toUnionResults) {
+ SimpleGeometryCursor inputGeometriesCursor = new SimpleGeometryCursor(
+ geometries);
+ GeometryCursor result = op.execute(inputGeometriesCursor,
+ spatialReference, bufferDistances, toUnionResults, null);
+
+ ArrayList resultGeoms = new ArrayList();
+ Geometry g;
+ while ((g = result.next()) != null) {
+ resultGeoms.add((Polygon) g);
+ }
+ Polygon[] buffers = resultGeoms.toArray(new Polygon[0]);
+ return buffers;
+ } else {
+ Polygon[] buffers = new Polygon[geometries.length];
+ for (int i = 0; i < geometries.length; i++) {
+ buffers[i] = (Polygon) op.execute(geometries[i],
+ spatialReference, bufferDistances[i], null);
+ }
+ return buffers;
+ }
+ }
+
+ /**
+ * Calculates a buffer polygon of the geometry as specified by the
+ * distance input. The buffer is implemented in the xy-plane.
+ *
+ * See OperatorBuffer
+ *
+ * @param geometry Geometry to be buffered.
+ * @param spatialReference The spatial reference of the geometry.
+ * @param distance The specified distance for buffer. Same units as the spatial reference.
+ * @return The buffer polygon at the specified distances.
+ */
+ public static Polygon buffer(Geometry geometry,
+ SpatialReference spatialReference, double distance) {
+ double bufferDistance = distance;
+
+ OperatorBuffer op = (OperatorBuffer) factory
+ .getOperator(Operator.Type.Buffer);
+ Geometry result = op.execute(geometry, spatialReference,
+ bufferDistance, null);
+ return (Polygon) result;
+ }
+
+ /**
+ * Calculates the convex hull geometry.
+ *
+ * See OperatorConvexHull.
+ *
+ * @param geometry The input geometry.
+ * @return Returns the convex hull.
+ *
+ * For a Point - returns the same point. For an Envelope -
+ * returns the same envelope. For a MultiPoint - If the point
+ * count is one, returns the same multipoint. If the point count
+ * is two, returns a polyline of the points. Otherwise computes
+ * and returns the convex hull polygon. For a Segment - returns a
+ * polyline consisting of the segment. For a Polyline - If
+ * consists of only one segment, returns the same polyline.
+ * Otherwise computes and returns the convex hull polygon. For a
+ * Polygon - If more than one path, or if the path isn't already
+ * convex, computes and returns the convex hull polygon.
+ * Otherwise returns the same polygon.
+ */
+ public static Geometry convexHull(Geometry geometry) {
+ OperatorConvexHull op = (OperatorConvexHull) factory
+ .getOperator(Operator.Type.ConvexHull);
+ return op.execute(geometry, null);
+ }
+
+ /**
+ * Calculates the convex hull.
+ *
+ * See OperatorConvexHull
+ *
+ * @param geometries
+ * The input geometry array.
+ * @param b_merge
+ * Put true if you want the convex hull of all the geometries in
+ * the array combined. Put false if you want the convex hull of
+ * each geometry in the array individually.
+ * @return Returns an array of convex hulls. If b_merge is true, the result
+ * will be a one element array consisting of the merged convex hull.
+ */
+ public static Geometry[] convexHull(Geometry[] geometries, boolean b_merge) {
+ OperatorConvexHull op = (OperatorConvexHull) factory
+ .getOperator(Operator.Type.ConvexHull);
+ SimpleGeometryCursor simple_cursor = new SimpleGeometryCursor(
+ geometries);
+ GeometryCursor cursor = op.execute(simple_cursor, b_merge, null);
+
+ ArrayList resultGeoms = new ArrayList();
+ Geometry g;
+ while ((g = cursor.next()) != null) {
+ resultGeoms.add(g);
+ }
+
+ Geometry[] output = new Geometry[resultGeoms.size()];
+
+ for (int i = 0; i < resultGeoms.size(); i++)
+ output[i] = resultGeoms.get(i);
+
+ return output;
+ }
+
+ /**
+ * Finds the coordinate of the geometry which is closest to the specified
+ * point.
+ *
+ * See OperatorProximity2D.
+ *
+ * @param inputPoint
+ * The point to find the nearest coordinate in the geometry for.
+ * @param geometry
+ * The geometry to consider.
+ * @return Proximity2DResult containing the nearest coordinate.
+ */
+ public static Proximity2DResult getNearestCoordinate(Geometry geometry,
+ Point inputPoint, boolean bTestPolygonInterior) {
+
+ OperatorProximity2D proximity = (OperatorProximity2D) factory
+ .getOperator(com.esri.core.geometry.Operator.Type.Proximity2D);
+ Proximity2DResult result = proximity.getNearestCoordinate(geometry,
+ inputPoint, bTestPolygonInterior);
+ return result;
+ }
+
+ /**
+ * Finds nearest vertex on the geometry which is closed to the specified
+ * point.
+ *
+ * See OperatorProximity2D.
+ *
+ * @param inputPoint
+ * The point to find the nearest vertex of the geometry for.
+ * @param geometry
+ * The geometry to consider.
+ * @return Proximity2DResult containing the nearest vertex.
+ */
+ public static Proximity2DResult getNearestVertex(Geometry geometry,
+ Point inputPoint) {
+ OperatorProximity2D proximity = (OperatorProximity2D) factory
+ .getOperator(com.esri.core.geometry.Operator.Type.Proximity2D);
+ Proximity2DResult result = proximity.getNearestVertex(geometry,
+ inputPoint);
+ return result;
+ }
+
+ /**
+ * Finds all vertices in the given distance from the specified point, sorted
+ * from the closest to the furthest.
+ *
+ * See OperatorProximity2D.
+ *
+ * @param inputPoint
+ * The point to start from.
+ * @param geometry
+ * The geometry to consider.
+ * @param searchRadius
+ * The search radius.
+ * @param maxVertexCountToReturn
+ * The maximum number number of vertices to return.
+ * @return Proximity2DResult containing the array of nearest vertices.
+ */
+ public static Proximity2DResult[] getNearestVertices(Geometry geometry,
+ Point inputPoint, double searchRadius, int maxVertexCountToReturn) {
+ OperatorProximity2D proximity = (OperatorProximity2D) factory
+ .getOperator(com.esri.core.geometry.Operator.Type.Proximity2D);
+
+ Proximity2DResult[] results = proximity.getNearestVertices(geometry,
+ inputPoint, searchRadius, maxVertexCountToReturn);
+
+ return results;
+ }
+
+ /**
+ * Performs the simplify operation on the geometry.
+ *
+ * See OperatorSimplify and See OperatorSimplifyOGC.
+ *
+ * @param geometry
+ * The geometry to be simplified.
+ * @param spatialReference
+ * The spatial reference of the geometry to be simplified.
+ * @return The simplified geometry.
+ */
+ public static Geometry simplify(Geometry geometry,
+ SpatialReference spatialReference) {
+ OperatorSimplify op = (OperatorSimplify) factory
+ .getOperator(Operator.Type.Simplify);
+ Geometry result = op.execute(geometry, spatialReference, false, null);
+ return result;
+ }
+
+ /**
+ * Checks if the Geometry is simple.
+ *
+ * See OperatorSimplify.
+ *
+ * @param geometry
+ * The geometry to be checked.
+ * @param spatialReference
+ * The spatial reference of the geometry.
+ * @return TRUE if the geometry is simple.
+ */
+ static boolean isSimple(Geometry geometry, SpatialReference spatialReference) {
+ OperatorSimplify op = (OperatorSimplify) factory
+ .getOperator(Operator.Type.Simplify);
+ boolean result = op.isSimpleAsFeature(geometry, spatialReference, null);
+ return result;
+ }
+
+ /**
+ * A geodesic distance is the shortest distance between any two points on the earth's surface when the earth's
+ * surface is approximated by a spheroid. The function returns the shortest distance between two points on the
+ * WGS84 spheroid.
+ * @param ptFrom The "from" point: long, lat in degrees.
+ * @param ptTo The "to" point: long, lat in degrees.
+ * @return The geodesic distance between two points in meters.
+ */
+ public static double geodesicDistanceOnWGS84(Point ptFrom, Point ptTo) {
+ return SpatialReferenceImpl.geodesicDistanceOnWGS84Impl(ptFrom, ptTo);
+ }
+}
diff --git a/src/com/esri/core/geometry/GeometryException.java b/src/main/java/com/esri/core/geometry/GeometryException.java
similarity index 82%
rename from src/com/esri/core/geometry/GeometryException.java
rename to src/main/java/com/esri/core/geometry/GeometryException.java
index 23e86829..97638685 100644
--- a/src/com/esri/core/geometry/GeometryException.java
+++ b/src/main/java/com/esri/core/geometry/GeometryException.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -31,10 +31,6 @@
public class GeometryException extends RuntimeException {
private static final long serialVersionUID = 1L;
- /**
- * The internal code for geometry exception.
- */
- public int internalCode;
/**
* Constructs a Geometry Exception with the given error string/message.
@@ -42,14 +38,11 @@ public class GeometryException extends RuntimeException {
* @param str
* - The error string.
*/
- GeometryException(String str) {
+ public GeometryException(String str) {
super(str);
- internalCode = 0;
}
- GeometryException(String str, int sgCode) {
- super(str);
- internalCode = sgCode;
+ static GeometryException GeometryInternalError() {
+ return new GeometryException("internal error");
}
-
}
diff --git a/src/com/esri/core/geometry/GeometrySerializer.java b/src/main/java/com/esri/core/geometry/GeometrySerializer.java
similarity index 97%
rename from src/com/esri/core/geometry/GeometrySerializer.java
rename to src/main/java/com/esri/core/geometry/GeometrySerializer.java
index 8bf9f401..a2fefa1e 100644
--- a/src/com/esri/core/geometry/GeometrySerializer.java
+++ b/src/main/java/com/esri/core/geometry/GeometrySerializer.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@
import java.io.ObjectStreamException;
import java.io.Serializable;
+//Left here for backward compatibility. Use GenericGeometrySerializer instead
+@Deprecated
final class GeometrySerializer implements Serializable {
private static final long serialVersionUID = 1L;
diff --git a/src/com/esri/core/geometry/IndexHashTable.java b/src/main/java/com/esri/core/geometry/IndexHashTable.java
similarity index 73%
rename from src/com/esri/core/geometry/IndexHashTable.java
rename to src/main/java/com/esri/core/geometry/IndexHashTable.java
index c9189770..b0117bb8 100644
--- a/src/com/esri/core/geometry/IndexHashTable.java
+++ b/src/main/java/com/esri/core/geometry/IndexHashTable.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,7 +23,9 @@
*/
package com.esri.core.geometry;
-class IndexHashTable {
+import java.util.Arrays;
+
+final class IndexHashTable {
// The hash function abstract class that user need to define to use the
// IndexHashTable.
public static abstract class HashFunction {
@@ -38,6 +40,8 @@ public static abstract class HashFunction {
int m_random;
AttributeStreamOfInt32 m_hashBuckets;
+ int [] m_bit_filter; //this is aimed to speedup the find
+ //operation and allows to have less buckets.
IndexMultiList m_lists;
HashFunction m_hash;
@@ -47,6 +51,7 @@ public IndexHashTable(int size, HashFunction hashFunction) {
m_hashBuckets = new AttributeStreamOfInt32(size, nullNode());
m_lists = new IndexMultiList();
m_hash = hashFunction;
+ m_bit_filter = new int[(size*10+31) >> 5]; //10 times more bits than buckets
}
public void reserveElements(int capacity) {
@@ -55,35 +60,76 @@ public void reserveElements(int capacity) {
}
// Adds new element to the hash table.
- public void addElement(int element) {
+ public int addElement(int element, int hash) {
+ int bit_bucket = hash % (m_bit_filter.length << 5);
+ m_bit_filter[(bit_bucket >> 5)] |= (1 << (bit_bucket & 0x1F));
+ int bucket = hash % m_hashBuckets.size();
+ int list = m_hashBuckets.get(bucket);
+ if (list == -1) {
+ list = m_lists.createList();
+ m_hashBuckets.set(bucket, list);
+ }
+ int node = m_lists.addElement(list, element);
+ return node;
+ }
+
+ public int addElement(int element) {
int hash = m_hash.getHash(element);
+ int bit_bucket = hash % (m_bit_filter.length << 5);
+ m_bit_filter[(bit_bucket >> 5)] |= (1 << (bit_bucket & 0x1F));
int bucket = hash % m_hashBuckets.size();
int list = m_hashBuckets.get(bucket);
- if (list == IndexMultiList.nullNode()) {
+ if (list == -1) {
list = m_lists.createList();
m_hashBuckets.set(bucket, list);
}
- m_lists.addElement(list, element);
+ int node = m_lists.addElement(list, element);
+ return node;
}
+ public void deleteElement(int element, int hash) {
+ int bucket = hash % m_hashBuckets.size();
+ int list = m_hashBuckets.get(bucket);
+ if (list == -1)
+ throw new IllegalArgumentException();
+
+ int ptr = m_lists.getFirst(list);
+ int prev = -1;
+ while (ptr != -1) {
+ int e = m_lists.getElement(ptr);
+ int nextptr = m_lists.getNext(ptr);
+ if (e == element) {
+ m_lists.deleteElement(list, prev, ptr);
+ if (m_lists.getFirst(list) == -1) {
+ m_lists.deleteList(list);// do not keep empty lists
+ m_hashBuckets.set(bucket, -1);
+ }
+ } else {
+ prev = ptr;
+ }
+ ptr = nextptr;
+ }
+
+ }
+
// Removes element from the hash table.
public void deleteElement(int element) {
int hash = m_hash.getHash(element);
int bucket = hash % m_hashBuckets.size();
int list = m_hashBuckets.get(bucket);
- if (list == IndexMultiList.nullNode())
+ if (list == -1)
throw new IllegalArgumentException();
int ptr = m_lists.getFirst(list);
- int prev = IndexMultiList.nullNode();
- while (ptr != IndexMultiList.nullNode()) {
+ int prev = -1;
+ while (ptr != -1) {
int e = m_lists.getElement(ptr);
int nextptr = m_lists.getNext(ptr);
if (e == element) {
m_lists.deleteElement(list, prev, ptr);
- if (m_lists.getFirst(list) == IndexMultiList.nullNode()) {
+ if (m_lists.getFirst(list) == -1) {
m_lists.deleteList(list);// do not keep empty lists
- m_hashBuckets.set(bucket, IndexMultiList.nullNode());
+ m_hashBuckets.set(bucket, -1);
}
} else {
prev = ptr;
@@ -96,10 +142,14 @@ public void deleteElement(int element) {
// Returns the first node in the hash table bucket defined by the given
// hashValue.
public int getFirstInBucket(int hashValue) {
+ int bit_bucket = hashValue % (m_bit_filter.length << 5);
+ if ((m_bit_filter[(bit_bucket >> 5)] & (1 << (bit_bucket & 0x1F))) == 0)
+ return -1;
+
int bucket = hashValue % m_hashBuckets.size();
int list = m_hashBuckets.get(bucket);
- if (list == IndexMultiList.nullNode())
- return IndexMultiList.nullNode();
+ if (list == -1)
+ return -1;
return m_lists.getFirst(list);
@@ -115,13 +165,8 @@ public int getNextInBucket(int elementHandle) {
// the given one.
public int findNode(int element) {
int hash = m_hash.getHash(element);
- int bucket = hash % m_hashBuckets.size();
- int list = m_hashBuckets.get(bucket);
- if (list == IndexMultiList.nullNode())
- return IndexMultiList.nullNode();
-
- int ptr = m_lists.getFirst(list);
- while (ptr != IndexMultiList.nullNode()) {
+ int ptr = getFirstInBucket(hash);
+ while (ptr != -1) {
int e = m_lists.getElement(ptr);
if (m_hash.equal(e, element)) {
return ptr;
@@ -129,7 +174,7 @@ public int findNode(int element) {
ptr = m_lists.getNext(ptr);
}
- return IndexMultiList.nullNode();
+ return -1;
}
@@ -137,13 +182,8 @@ public int findNode(int element) {
// the given element descriptor.
public int findNode(Object elementDescriptor) {
int hash = m_hash.getHash(elementDescriptor);
- int bucket = hash % m_hashBuckets.size();
- int list = m_hashBuckets.get(bucket);
- if (list == IndexMultiList.nullNode())
- return IndexMultiList.nullNode();
-
- int ptr = m_lists.getFirst(list);
- while (ptr != IndexMultiList.nullNode()) {
+ int ptr = getFirstInBucket(hash);;
+ while (ptr != -1) {
int e = m_lists.getElement(ptr);
if (m_hash.equal(elementDescriptor, e)) {
return ptr;
@@ -151,7 +191,7 @@ public int findNode(Object elementDescriptor) {
ptr = m_lists.getNext(ptr);
}
- return IndexMultiList.nullNode();
+ return -1;
}
@@ -159,7 +199,7 @@ public int findNode(Object elementDescriptor) {
public int getNextNode(int elementHandle) {
int element = m_lists.getElement(elementHandle);
int ptr = m_lists.getNext(elementHandle);
- while (ptr != IndexMultiList.nullNode()) {
+ while (ptr != -1) {
int e = m_lists.getElement(ptr);
if (m_hash.equal(e, element)) {
return ptr;
@@ -167,7 +207,7 @@ public int getNextNode(int elementHandle) {
ptr = m_lists.getNext(ptr);
}
- return IndexMultiList.nullNode();
+ return -1;
}
@@ -177,17 +217,17 @@ public void deleteNode(int node) {
int hash = m_hash.getHash(element);
int bucket = hash % m_hashBuckets.size();
int list = m_hashBuckets.get(bucket);
- if (list == IndexMultiList.nullNode())
+ if (list == -1)
throw new IllegalArgumentException();
int ptr = m_lists.getFirst(list);
- int prev = IndexMultiList.nullNode();
- while (ptr != IndexMultiList.nullNode()) {
+ int prev = -1;
+ while (ptr != -1) {
if (ptr == node) {
m_lists.deleteElement(list, prev, ptr);
- if (m_lists.getFirst(list) == IndexMultiList.nullNode()) {
+ if (m_lists.getFirst(list) == -1) {
m_lists.deleteList(list);// do not keep empty lists
- m_hashBuckets.set(bucket, IndexMultiList.nullNode());
+ m_hashBuckets.set(bucket, -1);
}
return;
}
@@ -217,11 +257,12 @@ public int getAnyNode() {
}
public static int nullNode() {
- return IndexMultiList.nullNode();
+ return -1;
}
// Removes all elements from the hash table.
public void clear() {
+ Arrays.fill(m_bit_filter, 0);
m_hashBuckets = new AttributeStreamOfInt32(m_hashBuckets.size(),
nullNode());
m_lists.clear();
diff --git a/src/com/esri/core/geometry/IndexMultiDCList.java b/src/main/java/com/esri/core/geometry/IndexMultiDCList.java
similarity index 99%
rename from src/com/esri/core/geometry/IndexMultiDCList.java
rename to src/main/java/com/esri/core/geometry/IndexMultiDCList.java
index b7a0a119..c20adbec 100644
--- a/src/com/esri/core/geometry/IndexMultiDCList.java
+++ b/src/main/java/com/esri/core/geometry/IndexMultiDCList.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/IndexMultiList.java b/src/main/java/com/esri/core/geometry/IndexMultiList.java
similarity index 99%
rename from src/com/esri/core/geometry/IndexMultiList.java
rename to src/main/java/com/esri/core/geometry/IndexMultiList.java
index 44b1da78..b008094a 100644
--- a/src/com/esri/core/geometry/IndexMultiList.java
+++ b/src/main/java/com/esri/core/geometry/IndexMultiList.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/InternalUtils.java b/src/main/java/com/esri/core/geometry/InternalUtils.java
similarity index 71%
rename from src/com/esri/core/geometry/InternalUtils.java
rename to src/main/java/com/esri/core/geometry/InternalUtils.java
index 81ebd259..257eb63f 100644
--- a/src/com/esri/core/geometry/InternalUtils.java
+++ b/src/main/java/com/esri/core/geometry/InternalUtils.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
import java.util.ArrayList;
-class InternalUtils {
+final class InternalUtils {
// p0 and p1 have to be on left/right boundary of fullRange2D (since this
// fuction can be called recursively, p0 or p1 can also be fullRange2D
@@ -108,9 +108,8 @@ void shiftPath(MultiPath inputGeom, int iPath, double shift) {
int i1 = inputGeom.getPathStart(iPath);
int i2 = inputGeom.getPathEnd(iPath);
- Point2D pt = new Point2D();// = null;
+ Point2D pt = new Point2D();
- // FIXME test to see if Point2D should be null
while (i1 < i2) {
xyStream.read(i1, pt);
pt.x += shift;
@@ -131,6 +130,10 @@ static double calculateToleranceFromGeometry(SpatialReference sr,
return Math.max(stolerance, gtolerance);
}
+ static double adjust_tolerance_for_TE_clustering(double tol) { return 2.0 * Math.sqrt(2.0) * tol; }
+
+ static double adjust_tolerance_for_TE_cracking(double tol) { return Math.sqrt(2.0) * tol; }
+
static double calculateToleranceFromGeometry(SpatialReference sr,
Geometry geometry, boolean bConservative) {
Envelope2D env2D = new Envelope2D();
@@ -240,6 +243,7 @@ static QuadTreeImpl buildQuadTree(MultiPathImpl multipathImpl) {
SegmentIteratorImpl seg_iter = multipathImpl.querySegmentIterator();
Envelope2D boundingbox = new Envelope2D();
boolean resized_extent = false;
+
while (seg_iter.nextPath()) {
while (seg_iter.hasNextSegment()) {
Segment segment = seg_iter.nextSegment();
@@ -250,7 +254,7 @@ static QuadTreeImpl buildQuadTree(MultiPathImpl multipathImpl) {
if (hint_index == -1) {
if (resized_extent)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// resize extent
multipathImpl.calculateEnvelope2D(extent, false);
@@ -287,7 +291,7 @@ static QuadTreeImpl buildQuadTree(MultiPathImpl multipathImpl,
if (hint_index == -1) {
if (resized_extent)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// resize extent
multipathImpl.calculateEnvelope2D(extent, false);
@@ -303,6 +307,48 @@ static QuadTreeImpl buildQuadTree(MultiPathImpl multipathImpl,
return quad_tree_impl;
}
+ static QuadTreeImpl buildQuadTreeForPaths(MultiPathImpl multipathImpl)
+ {
+ Envelope2D extent = new Envelope2D();
+ multipathImpl.queryLooseEnvelope2D(extent);
+ if (extent.isEmpty())
+ return null;
+
+ QuadTreeImpl quad_tree_impl = new QuadTreeImpl(extent, 8);
+ int hint_index = -1;
+ Envelope2D boundingbox = new Envelope2D();
+
+ boolean resized_extent = false;
+ do
+ {
+ for (int ipath = 0, npaths = multipathImpl.getPathCount(); ipath < npaths; ipath++)
+ {
+ multipathImpl.queryPathEnvelope2D(ipath, boundingbox);
+ hint_index = quad_tree_impl.insert(ipath, boundingbox, hint_index);
+
+ if (hint_index == -1)
+ {
+ if (resized_extent)
+ throw GeometryException.GeometryInternalError();
+
+ //This is usually happens because esri shape buffer contains geometry extent which is slightly different from the true extent.
+ //Recalculate extent
+ multipathImpl.calculateEnvelope2D(extent, false);
+ resized_extent = true;
+ quad_tree_impl.reset(extent, 8);
+ break; //break the for loop
+ }
+ else
+ {
+ resized_extent = false;
+ }
+ }
+
+ } while(resized_extent);
+
+ return quad_tree_impl;
+ }
+
static QuadTreeImpl buildQuadTree(MultiPointImpl multipointImpl) {
Envelope2D extent = new Envelope2D();
multipointImpl.queryLooseEnvelope2D(extent);
@@ -318,7 +364,7 @@ static QuadTreeImpl buildQuadTree(MultiPointImpl multipointImpl) {
if (element_handle == -1) {
if (resized_extent)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// resize extent
multipointImpl.calculateEnvelope2D(extent, false);
@@ -349,7 +395,7 @@ static QuadTreeImpl buildQuadTree(MultiPointImpl multipointImpl,
if (element_handle == -1) {
if (resized_extent)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// resize extent
resized_extent = true;
@@ -366,8 +412,7 @@ static QuadTreeImpl buildQuadTree(MultiPointImpl multipointImpl,
static Envelope2DIntersectorImpl getEnvelope2DIntersector(
MultiPathImpl multipathImplA, MultiPathImpl multipathImplB,
- double tolerance, AttributeStreamOfInt32 verticesA,
- AttributeStreamOfInt32 verticesB) {
+ double tolerance) {
Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
multipathImplA.queryLooseEnvelope2D(env_a);
multipathImplB.queryLooseEnvelope2D(env_b);
@@ -397,8 +442,7 @@ static Envelope2DIntersectorImpl getEnvelope2DIntersector(
b_found_red = true;
Envelope2D env = new Envelope2D();
env.setCoords(env_a);
- intersector.addRedEnvelope(env);
- verticesA.add(segIterA.getStartPointIndex());
+ intersector.addRedEnvelope(segIterA.getStartPointIndex(), env);
}
}
intersector.endRedConstruction();
@@ -419,8 +463,7 @@ static Envelope2DIntersectorImpl getEnvelope2DIntersector(
b_found_blue = true;
Envelope2D env = new Envelope2D();
env.setCoords(env_b);
- intersector.addBlueEnvelope(env);
- verticesB.add(segIterB.getStartPointIndex());
+ intersector.addBlueEnvelope(segIterB.getStartPointIndex(), env);
}
}
intersector.endBlueConstruction();
@@ -431,76 +474,94 @@ static Envelope2DIntersectorImpl getEnvelope2DIntersector(
return intersector;
}
- static Envelope2DIntersectorImpl getEnvelope2DIntersectorForOGCParts(
- MultiPathImpl multipathImplA, MultiPathImpl multipathImplB,
- double tolerance, AttributeStreamOfInt32 parts_a,
- AttributeStreamOfInt32 parts_b) {
- int type_a = multipathImplA.getType().value();
- int type_b = multipathImplB.getType().value();
+ static Envelope2DIntersectorImpl getEnvelope2DIntersectorForParts(
+ MultiPathImpl multipathImplA, MultiPathImpl multipathImplB,
+ double tolerance, boolean bExteriorOnlyA, boolean bExteriorOnlyB) {
+ int type_a = multipathImplA.getType().value();
+ int type_b = multipathImplB.getType().value();
- Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
- multipathImplA.queryLooseEnvelope2D(env_a);
- multipathImplB.queryLooseEnvelope2D(env_b);
- env_a.inflate(tolerance, tolerance);
- env_b.inflate(tolerance, tolerance);
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ multipathImplA.queryLooseEnvelope2D(env_a);
+ multipathImplB.queryLooseEnvelope2D(env_b);
+ env_a.inflate(tolerance, tolerance);
+ env_b.inflate(tolerance, tolerance);
- Envelope2D envInter = new Envelope2D();
- envInter.setCoords(env_a);
- envInter.intersect(env_b);
+ Envelope2D envInter = new Envelope2D();
+ envInter.setCoords(env_a);
+ envInter.intersect(env_b);
- Envelope2DIntersectorImpl intersector = new Envelope2DIntersectorImpl();
- intersector.setTolerance(tolerance);
+ Envelope2DIntersectorImpl intersector = new Envelope2DIntersectorImpl();
+ intersector.setTolerance(tolerance);
- boolean b_found_red = false;
- intersector.startRedConstruction();
- for (int ipath_a = 0; ipath_a < multipathImplA.getPathCount(); ipath_a++) {
- if (type_a == Geometry.GeometryType.Polygon
- && !multipathImplA.isExteriorRing(ipath_a))
- continue;
+ boolean b_found_red = false;
+ intersector.startRedConstruction();
+ for (int ipath_a = 0, npaths = multipathImplA.getPathCount(); ipath_a < npaths; ipath_a++) {
+ if (bExteriorOnlyA && type_a == Geometry.GeometryType.Polygon && !multipathImplA.isExteriorRing(ipath_a))
+ continue;
- multipathImplA.queryPathEnvelope2D(ipath_a, env_a);
+ multipathImplA.queryPathEnvelope2D(ipath_a, env_a);
- if (!env_a.isIntersecting(envInter))
- continue;
+ if (!env_a.isIntersecting(envInter))
+ continue;
- b_found_red = true;
- Envelope2D env = new Envelope2D();
- env.setCoords(env_a);
- intersector.addRedEnvelope(env);
- parts_a.add(ipath_a);
- }
- intersector.endRedConstruction();
+ b_found_red = true;
+ intersector.addRedEnvelope(ipath_a, env_a);
+ }
+ intersector.endRedConstruction();
- if (!b_found_red)
- return null;
+ if (!b_found_red)
+ return null;
- boolean b_found_blue = false;
- intersector.startBlueConstruction();
- for (int ipath_b = 0; ipath_b < multipathImplB.getPathCount(); ipath_b++) {
- if (type_b == Geometry.GeometryType.Polygon
- && !multipathImplB.isExteriorRing(ipath_b))
- continue;
+ boolean b_found_blue = false;
+ intersector.startBlueConstruction();
+ for (int ipath_b = 0, npaths = multipathImplB.getPathCount(); ipath_b < npaths; ipath_b++) {
+ if (bExteriorOnlyB && type_b == Geometry.GeometryType.Polygon && !multipathImplB.isExteriorRing(ipath_b))
+ continue;
- multipathImplB.queryPathEnvelope2D(ipath_b, env_b);
+ multipathImplB.queryPathEnvelope2D(ipath_b, env_b);
- if (!env_b.isIntersecting(envInter))
- continue;
+ if (!env_b.isIntersecting(envInter))
+ continue;
- b_found_blue = true;
- Envelope2D env = new Envelope2D();
- env.setCoords(env_b);
- intersector.addBlueEnvelope(env);
- parts_b.add(ipath_b);
- }
- intersector.endBlueConstruction();
+ b_found_blue = true;
+ intersector.addBlueEnvelope(ipath_b, env_b);
+ }
+ intersector.endBlueConstruction();
- if (!b_found_blue)
- return null;
+ if (!b_found_blue)
+ return null;
- return intersector;
- }
+ return intersector;
+ }
static boolean isWeakSimple(MultiVertexGeometry geom, double tol) {
return ((MultiVertexGeometryImpl) geom._getImpl()).getIsSimple(tol) > 0;
}
+
+ static QuadTree buildQuadTreeForOnePath(MultiPathImpl multipathImpl, int path) {
+ Envelope2D extent = new Envelope2D();
+ multipathImpl.queryLoosePathEnvelope2D(path, extent);
+ QuadTree quad_tree = new QuadTree(extent, 8);
+ int hint_index = -1;
+ Envelope2D boundingbox = new Envelope2D();
+ SegmentIteratorImpl seg_iter = multipathImpl.querySegmentIterator();
+
+ seg_iter.resetToPath(path);
+ if (seg_iter.nextPath()) {
+ while (seg_iter.hasNextSegment()) {
+ Segment segment = seg_iter.nextSegment();
+ int index = seg_iter.getStartPointIndex();
+ segment.queryLooseEnvelope2D(boundingbox);
+ hint_index = quad_tree.insert(index, boundingbox, hint_index);
+
+ if (hint_index == -1) {
+ throw new GeometryException("internal error");
+ }
+ }
+ }
+
+ return quad_tree;
+ }
+
}
+
diff --git a/src/com/esri/core/geometry/Interop.java b/src/main/java/com/esri/core/geometry/Interop.java
similarity index 97%
rename from src/com/esri/core/geometry/Interop.java
rename to src/main/java/com/esri/core/geometry/Interop.java
index 38df1b52..b47801c7 100644
--- a/src/com/esri/core/geometry/Interop.java
+++ b/src/main/java/com/esri/core/geometry/Interop.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/IntervalTreeImpl.java b/src/main/java/com/esri/core/geometry/IntervalTreeImpl.java
similarity index 54%
rename from src/com/esri/core/geometry/IntervalTreeImpl.java
rename to src/main/java/com/esri/core/geometry/IntervalTreeImpl.java
index 4dd5594c..f7248c47 100644
--- a/src/com/esri/core/geometry/IntervalTreeImpl.java
+++ b/src/main/java/com/esri/core/geometry/IntervalTreeImpl.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,504 +26,452 @@
import java.util.ArrayList;
final class IntervalTreeImpl {
- static final class IntervalTreeIteratorImpl {
- /**
- * Resets the iterator to a starting state on the Interval_tree_impl
- * using the input Envelope_1D interval as the query \param query The
- * Envelope_1D interval used for the query. \param tolerance The
- * tolerance used for the intersection tests.
- */
- void resetIterator(Envelope1D query, double tolerance) {
- m_query.vmin = query.vmin - tolerance;
- m_query.vmax = query.vmax + tolerance;
- m_tertiary_stack.resize(0);
- m_function_index = 0;
- m_function_stack[0] = State.initialize;
- }
+ private void sortEndIndices_(AttributeStreamOfInt32 end_indices, int begin_, int end_) {
+ IntervalTreeBucketSortHelper sorter = new IntervalTreeBucketSortHelper(this);
+ BucketSort bucket_sort = new BucketSort();
+ bucket_sort.sort(end_indices, begin_, end_, sorter);
+ }
- /**
- * Resets the iterator to a starting state on the Interval_tree_impl
- * using the input Envelope_1D interval as the query \param query The
- * Envelope_1D interval used for the query. \param tolerance The
- * tolerance used for the intersection tests.
- */
- void resetIterator(double query_min, double query_max, double tolerance) {
- if (query_min > query_max)
- throw new IllegalArgumentException();
+ private void sortEndIndicesHelper_(AttributeStreamOfInt32 end_indices, int begin_, int end_) {
+ end_indices.Sort(begin_, end_, new EndPointsComparer(this));
+ }
- m_query.vmin = query_min - tolerance;
- m_query.vmax = query_max + tolerance;
- m_tertiary_stack.resize(0);
- m_function_index = 0;
- m_function_stack[0] = State.initialize;
+ private double getValue_(int e) {
+ if (!m_b_envelopes_ref) {
+ Envelope1D interval = m_intervals.get(e >> 1);
+ double v = (isLeft_(e) ? interval.vmin : interval.vmax);
+ return v;
}
- /**
- * Resets the iterator to a starting state on the Interval_tree_impl
- * using the input double as the stabbing query \param query The double
- * used for the query. \param tolerance The tolerance used for the
- * intersection tests.
- */
- void resetIterator(double query, double tolerance) {
- m_query.vmin = query - tolerance;
- m_query.vmax = query + tolerance;
- m_tertiary_stack.resize(0);
- m_function_index = 0;
- m_function_stack[0] = State.initialize;
+ Envelope2D interval = m_envelopes_ref.get(e >> 1);
+ double v = (isLeft_(e) ? interval.xmin : interval.xmax);
+ return v;
+ }
+
+ private static final class EndPointsComparer extends AttributeStreamOfInt32.IntComparator { // For user sort
+
+ EndPointsComparer(IntervalTreeImpl interval_tree) {
+ m_interval_tree = interval_tree;
}
- /**
- * Iterates over all intervals which interset the query interval.
- * Returns an index to an interval that intersects the query.
- */
- int next() {
- if (!m_interval_tree.m_b_construction_ended)
- throw new GeometryException("invalid call");
+ @Override
+ public int compare(int e_1, int e_2) {
+ double v_1 = m_interval_tree.getValue_(e_1);
+ double v_2 = m_interval_tree.getValue_(e_2);
- if (m_function_index < 0)
+ if (v_1 < v_2 || (v_1 == v_2 && isLeft_(e_1) && isRight_(e_2)))
return -1;
- boolean b_searching = true;
-
- while (b_searching) {
- switch (m_function_stack[m_function_index]) {
- case State.pIn:
- b_searching = pIn_();
- break;
- case State.pL:
- b_searching = pL_();
- break;
- case State.pR:
- b_searching = pR_();
- break;
- case State.pT:
- b_searching = pT_();
- break;
- case State.right:
- b_searching = right_();
- break;
- case State.left:
- b_searching = left_();
- break;
- case State.all:
- b_searching = all_();
- break;
- case State.initialize:
- b_searching = initialize_();
- break;
- default:
- throw new GeometryException("internal error");
- }
- }
+ return 1;
+ }
- if (m_current_end_handle != -1)
- return getCurrentEndIndex_() >> 1;
+ private IntervalTreeImpl m_interval_tree;
+ }
- return -1;
- }
+ private class IntervalTreeBucketSortHelper extends ClassicSort { // For bucket sort
- // Creates an iterator on the input Interval_tree using the input
- // Envelope_1D interval as the query.
- IntervalTreeIteratorImpl(IntervalTreeImpl interval_tree,
- Envelope1D query, double tolerance) {
+ IntervalTreeBucketSortHelper(IntervalTreeImpl interval_tree) {
m_interval_tree = interval_tree;
- m_tertiary_stack.reserve(20);
- resetIterator(query, tolerance);
}
- // Creates an iterator on the input Interval_tree using the input double
- // as the stabbing query.
- IntervalTreeIteratorImpl(IntervalTreeImpl interval_tree, double query,
- double tolerance) {
- m_interval_tree = interval_tree;
- m_tertiary_stack.reserve(20);
- resetIterator(query, tolerance);
+ @Override
+ public void userSort(int begin, int end, AttributeStreamOfInt32 indices) {
+ m_interval_tree.sortEndIndicesHelper_(indices, begin, end);
}
- // Creates an iterator on the input Interval_tree.
- IntervalTreeIteratorImpl(IntervalTreeImpl interval_tree) {
- m_interval_tree = interval_tree;
- m_tertiary_stack.reserve(20);
- m_function_index = -1;
+ @Override
+ public double getValue(int e) {
+ return m_interval_tree.getValue_(e);
}
private IntervalTreeImpl m_interval_tree;
- private Envelope1D m_query = new Envelope1D();
- private int m_primary_handle;
- private int m_next_primary_handle;
- private int m_forked_handle;
- private int m_current_end_handle;
- private int m_next_end_handle;
- private AttributeStreamOfInt32 m_tertiary_stack = new AttributeStreamOfInt32(
- 0);
- private int m_function_index;
- private int[] m_function_stack = new int[2];
+ }
- private interface State {
- static final int initialize = 0;
- static final int pIn = 1;
- static final int pL = 2;
- static final int pR = 3;
- static final int pT = 4;
- static final int right = 5;
- static final int left = 6;
- static final int all = 7;
- }
+ IntervalTreeImpl(boolean b_offline_dynamic) {
+ m_b_envelopes_ref = false;
+ m_b_offline_dynamic = b_offline_dynamic;
+ m_b_constructing = false;
+ m_b_construction_ended = false;
+ }
- private boolean initialize_() {
- m_primary_handle = -1;
- m_next_primary_handle = -1;
- m_forked_handle = -1;
- m_current_end_handle = -1;
+ void addEnvelopesRef(ArrayList envelopes) {
+ reset_(true, true);
+ m_b_envelopes_ref = true;
+ m_envelopes_ref = envelopes;
- if (m_interval_tree.m_primary_nodes != null
- && m_interval_tree.m_primary_nodes.size() > 0) {
- m_function_stack[0] = State.pIn; // overwrite initialize
- m_next_primary_handle = m_interval_tree.m_root;
- return true;
- }
+ m_b_constructing = false;
+ m_b_construction_ended = true;
- m_function_index = -1;
- return false;
+ if (!m_b_offline_dynamic) {
+ insertIntervalsStatic_();
+ m_c_count = m_envelopes_ref.size();
}
+ }
- private boolean pIn_() {
- m_primary_handle = m_next_primary_handle;
+ void startConstruction() {
+ reset_(true, false);
+ }
- if (m_primary_handle == -1) {
- m_function_index = -1;
- m_current_end_handle = -1;
- return false;
- }
+ void addInterval(Envelope1D interval) {
+ if (!m_b_constructing)
+ throw new GeometryException("invalid call");
- double discriminant = m_interval_tree
- .getDiscriminant_(m_primary_handle);
+ m_intervals.add(interval);
+ }
- if (m_query.vmax < discriminant) {
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
- m_next_primary_handle = m_interval_tree
- .getLPTR_(m_primary_handle);
+ void addInterval(double min, double max) {
+ if (!m_b_constructing)
+ throw new GeometryException("invald call");
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree
- .getFirst_(secondary_handle);
- m_function_stack[++m_function_index] = State.left;
- }
+ m_intervals.add(new Envelope1D(min, max));
+ }
- return true;
- }
+ void endConstruction() {
+ if (!m_b_constructing)
+ throw new GeometryException("invalid call");
- if (discriminant < m_query.vmin) {
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
- m_next_primary_handle = m_interval_tree
- .getRPTR_(m_primary_handle);
+ m_b_constructing = false;
+ m_b_construction_ended = true;
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree
- .getLast_(secondary_handle);
- m_function_stack[++m_function_index] = State.right;
- }
+ if (!m_b_offline_dynamic) {
+ insertIntervalsStatic_();
+ m_c_count = m_intervals.size();
+ }
+ }
- return true;
- }
+ /*
+ * Resets the Interval_tree_impl to an empty state, but maintains a handle
+ * on the current intervals.
+ */
+ void reset() {
+ if (!m_b_offline_dynamic || !m_b_construction_ended)
+ throw new IllegalArgumentException("invalid call");
- assert (m_query.contains(discriminant));
+ reset_(false, m_b_envelopes_ref);
+ }
- m_function_stack[m_function_index] = State.pL; // overwrite pIn
- m_forked_handle = m_primary_handle;
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
- m_next_primary_handle = m_interval_tree.getLPTR_(m_primary_handle);
+ /**
+ * Returns the number of intervals stored in the Interval_tree_impl
+ */
+ int size() {
+ return m_c_count;
+ }
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
- m_function_stack[++m_function_index] = State.all;
- }
+ /**
+ * Gets an iterator on the Interval_tree_impl using the input Envelope_1D
+ * interval as the query. To reuse the existing iterator on the same
+ * Interval_tree_impl but with a new query, use the reset_iterator function
+ * on the Interval_tree_iterator_impl. \param query The Envelope_1D interval
+ * used for the query. \param tolerance The tolerance used for the
+ * intersection tests.
+ */
+ IntervalTreeIteratorImpl getIterator(Envelope1D query, double tolerance) {
+ return new IntervalTreeImpl.IntervalTreeIteratorImpl(this, query, tolerance);
+ }
- return true;
- }
+ /**
+ * Gets an iterator on the Interval_tree_impl using the input double as the
+ * stabbing query. To reuse the existing iterator on the same
+ * Interval_tree_impl but with a new query, use the reset_iterator function
+ * on the Interval_tree_iterator_impl. \param query The double used for the
+ * stabbing query. \param tolerance The tolerance used for the intersection
+ * tests.
+ */
+ IntervalTreeIteratorImpl getIterator(double query, double tolerance) {
+ return new IntervalTreeImpl.IntervalTreeIteratorImpl(this, query, tolerance);
+ }
- private boolean pL_() {
- m_primary_handle = m_next_primary_handle;
+ /**
+ * Gets an iterator on the Interval_tree_impl.
+ */
+ IntervalTreeIteratorImpl getIterator() {
+ return new IntervalTreeImpl.IntervalTreeIteratorImpl(this);
+ }
- if (m_primary_handle == -1) {
- m_function_stack[m_function_index] = State.pR; // overwrite pL
- m_next_primary_handle = m_interval_tree
- .getRPTR_(m_forked_handle);
- return true;
- }
+ private boolean m_b_envelopes_ref;
+ private boolean m_b_offline_dynamic;
+ private ArrayList m_intervals;
+ private ArrayList m_envelopes_ref;
+ private StridedIndexTypeCollection m_tertiary_nodes; // 5 elements for offline dynamic case, 4 elements for static case
+ private StridedIndexTypeCollection m_interval_nodes; // 3 elements
+ private AttributeStreamOfInt32 m_interval_handles; // for offline dynamic// case
+ private IndexMultiDCList m_secondary_lists; // for static case
+ private Treap m_secondary_treaps; // for off-line dynamic case
+ private AttributeStreamOfInt32 m_end_indices_unique; // for both offline dynamic and static cases
+ private int m_c_count;
+ private int m_root;
+ private boolean m_b_sort_intervals;
+ private boolean m_b_constructing;
+ private boolean m_b_construction_ended;
- double discriminant = m_interval_tree
- .getDiscriminant_(m_primary_handle);
+ /* m_tertiary_nodes
+ * 0: m_discriminant_index_1
+ * 1: m_secondary
+ * 2: m_lptr
+ * 3: m_rptr
+ * 4: m_pptr
+ */
- if (discriminant < m_query.vmin) {
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
- m_next_primary_handle = m_interval_tree
- .getRPTR_(m_primary_handle);
+ private void querySortedEndPointIndices_(AttributeStreamOfInt32 end_indices) {
+ int size = (!m_b_envelopes_ref ? m_intervals.size() : m_envelopes_ref.size());
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree
- .getLast_(secondary_handle);
- m_function_stack[++m_function_index] = State.right;
- }
+ for (int i = 0; i < 2 * size; i++)
+ end_indices.add(i);
- return true;
- }
+ sortEndIndices_(end_indices, 0, 2 * size);
+ }
- assert (m_query.contains(discriminant));
+ private void querySortedDuplicatesRemoved_(AttributeStreamOfInt32 end_indices_sorted) {
+ // remove duplicates
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
- m_next_primary_handle = m_interval_tree.getLPTR_(m_primary_handle);
+ double prev = NumberUtils.TheNaN;
+ for (int i = 0; i < end_indices_sorted.size(); i++) {
+ int e = end_indices_sorted.get(i);
+ double v = getValue_(e);
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
- m_function_stack[++m_function_index] = State.all;
+ if (v != prev) {
+ m_end_indices_unique.add(e);
+ prev = v;
}
+ }
+ }
- int rptr = m_interval_tree.getRPTR_(m_primary_handle);
+ void insert(int index) {
+ if (!m_b_offline_dynamic || !m_b_construction_ended)
+ throw new IllegalArgumentException("invalid call");
- if (rptr != -1) {
- m_tertiary_stack.add(rptr); // we'll search this in the pT state
- }
+ if (m_root == -1) {
- return true;
- }
+ int size = (!m_b_envelopes_ref ? m_intervals.size() : m_envelopes_ref.size());
- private boolean pR_() {
- m_primary_handle = m_next_primary_handle;
+ if (m_b_sort_intervals) {
+ // sort
+ AttributeStreamOfInt32 end_point_indices_sorted = new AttributeStreamOfInt32(0);
+ end_point_indices_sorted.reserve(2 * size);
+ querySortedEndPointIndices_(end_point_indices_sorted);
- if (m_primary_handle == -1) {
- m_function_stack[m_function_index] = State.pT; // overwrite pR
- return true;
+ // remove duplicates
+ m_end_indices_unique.resize(0);
+ querySortedDuplicatesRemoved_(end_point_indices_sorted);
+ m_interval_handles.resize(size, -1);
+ m_interval_handles.setRange(-1, 0, size);
+ m_b_sort_intervals = false;
+ } else {
+ m_interval_handles.setRange(-1, 0, size);
}
- double discriminant = m_interval_tree
- .getDiscriminant_(m_primary_handle);
+ m_root = createRoot_();
+ }
- if (m_query.vmax < discriminant) {
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
- m_next_primary_handle = m_interval_tree
- .getLPTR_(m_primary_handle);
+ int interval_handle = insertIntervalEnd_(index << 1, m_root);
+ int secondary_handle = getSecondaryFromInterval_(interval_handle);
+ int right_end_handle = m_secondary_treaps.addElement((index << 1) + 1, secondary_handle);
+ setRightEnd_(interval_handle, right_end_handle);
+ m_interval_handles.set(index, interval_handle);
+ m_c_count++;
+ // assert(check_validation_());
+ }
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree
- .getFirst_(secondary_handle);
- m_function_stack[++m_function_index] = State.left;
- }
+ private void insertIntervalsStatic_() {
+ int size = (!m_b_envelopes_ref ? m_intervals.size() : m_envelopes_ref.size());
- return true;
- }
+ assert (m_b_sort_intervals);
- assert (m_query.contains(discriminant));
+ // sort
+ AttributeStreamOfInt32 end_indices_sorted = new AttributeStreamOfInt32(0);
+ end_indices_sorted.reserve(2 * size);
+ querySortedEndPointIndices_(end_indices_sorted);
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
+ // remove duplicates
+ m_end_indices_unique.resize(0);
+ querySortedDuplicatesRemoved_(end_indices_sorted);
- m_next_primary_handle = m_interval_tree.getRPTR_(m_primary_handle);
+ assert (m_tertiary_nodes.size() == 0);
+ m_interval_nodes.setCapacity(size); // one for each interval being inserted. each element contains a tertiary node, a left secondary node, and a right secondary node.
+ m_secondary_lists.reserveNodes(2 * size); // one for each end point of the original interval set (not the unique set)
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
- m_function_stack[++m_function_index] = State.all;
- }
+ AttributeStreamOfInt32 interval_handles = (AttributeStreamOfInt32) AttributeStreamBase.createIndexStream(size);
+ interval_handles.setRange(-1, 0, size);
- int lptr = m_interval_tree.getLPTR_(m_primary_handle);
+ m_root = createRoot_();
- if (lptr != -1) {
- m_tertiary_stack.add(lptr); // we'll search this in the pT state
- }
+ for (int i = 0; i < end_indices_sorted.size(); i++) {
+ int e = end_indices_sorted.get(i);
+ int interval_handle = interval_handles.get(e >> 1);
- return true;
+ if (interval_handle != -1) {// insert the right end point
+ assert (isRight_(e));
+ int secondary_handle = getSecondaryFromInterval_(interval_handle);
+ setRightEnd_(interval_handle, m_secondary_lists.addElement(secondary_handle, e));
+ } else {// insert the left end point
+ assert (isLeft_(e));
+ interval_handle = insertIntervalEnd_(e, m_root);
+ interval_handles.set(e >> 1, interval_handle);
+ }
}
- private boolean pT_() {
- if (m_tertiary_stack.size() == 0) {
- m_function_index = -1;
- m_current_end_handle = -1;
- return false;
- }
+ assert (m_secondary_lists.getNodeCount() == 2 * size);
+ }
- m_primary_handle = m_tertiary_stack
- .get(m_tertiary_stack.size() - 1);
- m_tertiary_stack.resize(m_tertiary_stack.size() - 1);
+ private int createRoot_() {
+ int discriminant_index_1 = calculateDiscriminantIndex1_(0, m_end_indices_unique.size() - 1);
+ return createTertiaryNode_(discriminant_index_1);
+ }
- int secondary_handle = m_interval_tree
- .getSecondaryFromPrimary(m_primary_handle);
+ private int insertIntervalEnd_(int end_index, int root) {
+ assert (isLeft_(end_index));
+ int pptr = -1;
+ int ptr = root;
+ int secondary_handle = -1;
+ int interval_handle = -1;
+ int il = 0, ir = m_end_indices_unique.size() - 1, im = 0;
+ int index = end_index >> 1;
+ double discriminant_pptr = NumberUtils.NaN();
+ double discriminant_ptr = NumberUtils.NaN();
+ boolean bSearching = true;
- if (secondary_handle != -1) {
- m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
- m_function_stack[++m_function_index] = State.all;
- }
+ double min = getMin_(index);
+ double max = getMax_(index);
- if (m_interval_tree.getLPTR_(m_primary_handle) != -1)
- m_tertiary_stack
- .add(m_interval_tree.getLPTR_(m_primary_handle));
+ int discriminant_index_1 = -1;
- if (m_interval_tree.getRPTR_(m_primary_handle) != -1)
- m_tertiary_stack
- .add(m_interval_tree.getRPTR_(m_primary_handle));
+ while (bSearching) {
+ im = il + (ir - il) / 2;
+ assert (il != ir || min == max);
+ discriminant_index_1 = calculateDiscriminantIndex1_(il, ir);
+ double discriminant = getDiscriminantFromIndex1_(discriminant_index_1);
+ assert (!NumberUtils.isNaN(discriminant));
- return true;
- }
+ if (max < discriminant) {
+ if (ptr != -1) {
+ if (discriminant_index_1 == getDiscriminantIndex1_(ptr)) {
+ assert (getDiscriminantFromIndex1_(discriminant_index_1) == getDiscriminant_(ptr));
- private boolean left_() {
- m_current_end_handle = m_next_end_handle;
+ pptr = ptr;
+ discriminant_pptr = discriminant;
+ ptr = getLPTR_(ptr);
- if (m_current_end_handle != -1
- && IntervalTreeImpl.isLeft_(getCurrentEndIndex_())
- && m_interval_tree.getValue_(getCurrentEndIndex_()) <= m_query.vmax) {
- m_next_end_handle = getNext_();
- return false;
- }
+ if (ptr != -1)
+ discriminant_ptr = getDiscriminant_(ptr);
+ else
+ discriminant_ptr = NumberUtils.NaN();
+ } else if (discriminant_ptr > discriminant) {
+ int tertiary_handle = createTertiaryNode_(discriminant_index_1);
- m_function_index--;
- return true;
- }
+ if (discriminant < discriminant_pptr)
+ setLPTR_(pptr, tertiary_handle);
+ else
+ setRPTR_(pptr, tertiary_handle);
- private boolean right_() {
- m_current_end_handle = m_next_end_handle;
+ setRPTR_(tertiary_handle, ptr);
- if (m_current_end_handle != -1
- && IntervalTreeImpl.isRight_(getCurrentEndIndex_())
- && m_interval_tree.getValue_(getCurrentEndIndex_()) >= m_query.vmin) {
- m_next_end_handle = getPrev_();
- return false;
- }
+ if (m_b_offline_dynamic) {
+ setPPTR_(tertiary_handle, pptr);
+ setPPTR_(ptr, tertiary_handle);
+ }
- m_function_index--;
- return true;
- }
+ pptr = tertiary_handle;
+ discriminant_pptr = discriminant;
+ ptr = -1;
+ discriminant_ptr = NumberUtils.NaN();
+ }
+ }
- private boolean all_() {
- m_current_end_handle = m_next_end_handle;
+ ir = im;
- if (m_current_end_handle != -1
- && IntervalTreeImpl.isLeft_(getCurrentEndIndex_())) {
- m_next_end_handle = getNext_();
- return false;
+ continue;
}
- m_function_index--;
- return true;
- }
-
- private int getNext_() {
- if (!m_interval_tree.m_b_offline_dynamic)
- return m_interval_tree.m_secondary_lists
- .getNext(m_current_end_handle);
-
- return m_interval_tree.m_secondary_treaps
- .getNext(m_current_end_handle);
- }
+ if (min > discriminant) {
+ if (ptr != -1) {
+ if (discriminant_index_1 == getDiscriminantIndex1_(ptr)) {
+ assert (getDiscriminantFromIndex1_(discriminant_index_1) == getDiscriminant_(ptr));
- private int getPrev_() {
- if (!m_interval_tree.m_b_offline_dynamic)
- return m_interval_tree.m_secondary_lists
- .getPrev(m_current_end_handle);
+ pptr = ptr;
+ discriminant_pptr = discriminant;
+ ptr = getRPTR_(ptr);
- return m_interval_tree.m_secondary_treaps
- .getPrev(m_current_end_handle);
- }
+ if (ptr != -1)
+ discriminant_ptr = getDiscriminant_(ptr);
+ else
+ discriminant_ptr = NumberUtils.NaN();
+ } else if (discriminant_ptr < discriminant) {
+ int tertiary_handle = createTertiaryNode_(discriminant_index_1);
- private int getCurrentEndIndex_() {
- if (!m_interval_tree.m_b_offline_dynamic)
- return m_interval_tree.m_secondary_lists
- .getData(m_current_end_handle);
+ if (discriminant < discriminant_pptr)
+ setLPTR_(pptr, tertiary_handle);
+ else
+ setRPTR_(pptr, tertiary_handle);
- return m_interval_tree.m_secondary_treaps
- .getElement(m_current_end_handle);
- }
- }
+ setLPTR_(tertiary_handle, ptr);
- IntervalTreeImpl(boolean b_offline_dynamic) {
- m_b_offline_dynamic = b_offline_dynamic;
- m_b_constructing = false;
- m_b_construction_ended = false;
- }
+ if (m_b_offline_dynamic) {
+ setPPTR_(tertiary_handle, pptr);
+ setPPTR_(ptr, tertiary_handle);
+ }
- void startConstruction() {
- reset_(true);
- }
+ pptr = tertiary_handle;
+ discriminant_pptr = discriminant;
+ ptr = -1;
+ discriminant_ptr = NumberUtils.NaN();
+ }
+ }
- void addInterval(Envelope1D interval) {
- if (!m_b_constructing)
- throw new GeometryException("invalid call");
+ il = im + 1;
- m_intervals.add(interval);
- }
+ continue;
+ }
- void addInterval(double min, double max) {
- if (!m_b_constructing)
- throw new GeometryException("invald call");
+ int tertiary_handle = -1;
- m_intervals.add(new Envelope1D(min, max));
- }
+ if (ptr == -1 || discriminant_index_1 != getDiscriminantIndex1_(ptr)) {
+ tertiary_handle = createTertiaryNode_(discriminant_index_1);
+ } else {
+ tertiary_handle = ptr;
+ }
- void endConstruction() {
- if (!m_b_constructing)
- throw new GeometryException("invalid call");
+ secondary_handle = getSecondaryFromTertiary_(tertiary_handle);
- m_b_constructing = false;
- m_b_construction_ended = true;
+ if (secondary_handle == -1) {
+ secondary_handle = createSecondary_(tertiary_handle);
+ setSecondaryToTertiary_(tertiary_handle, secondary_handle);
+ }
- if (!m_b_offline_dynamic) {
- insertIntervalsStatic_();
- m_c_count = m_intervals.size();
- }
- }
+ int left_end_handle = addEndIndex_(secondary_handle, end_index);
+ interval_handle = createIntervalNode_();
+ setSecondaryToInterval_(interval_handle, secondary_handle);
+ setLeftEnd_(interval_handle, left_end_handle);
- /**
- * Inserts the interval from the given index into the Interval_tree_impl.
- * This operation can only be performed in the offline dynamic case. \param
- * index The index containing the interval to be inserted.
- */
- void insert(int index) {
- if (!m_b_offline_dynamic || !m_b_construction_ended)
- throw new IllegalArgumentException("invalid call");
+ if (ptr == -1 || discriminant_index_1 != getDiscriminantIndex1_(ptr)) {
+ assert (tertiary_handle != -1);
+ assert (getLPTR_(tertiary_handle) == -1 && getRPTR_(tertiary_handle) == -1 && (!m_b_offline_dynamic || getPPTR_(tertiary_handle) == -1));
- if (m_root == -1) {
+ if (discriminant < discriminant_pptr)
+ setLPTR_(pptr, tertiary_handle);
+ else
+ setRPTR_(pptr, tertiary_handle);
- int size = m_intervals.size();
+ if (m_b_offline_dynamic)
+ setPPTR_(tertiary_handle, pptr);
- if (m_b_sort_intervals) {
- // sort
- AttributeStreamOfInt32 end_point_indices_sorted = new AttributeStreamOfInt32(
- 0);
- end_point_indices_sorted.reserve(2 * size);
- querySortedEndPointIndices_(end_point_indices_sorted);
+ if (ptr != -1) {
+ if (discriminant_ptr < discriminant)
+ setLPTR_(tertiary_handle, ptr);
+ else
+ setRPTR_(tertiary_handle, ptr);
- // remove duplicates
- m_end_indices_unique.reserve(2 * size);
- m_end_indices_unique.resize(0);
- querySortedDuplicatesRemoved_(end_point_indices_sorted);
- m_interval_handles.resize(size, -1);
- m_interval_handles.setRange(-1, 0, size);
- m_b_sort_intervals = false;
- } else {
- m_interval_handles.setRange(-1, 0, size);
+ if (m_b_offline_dynamic)
+ setPPTR_(ptr, tertiary_handle);
+ }
}
- m_root = createPrimaryNode_();
+ bSearching = false;
+ break;
}
- int interval_handle = insertIntervalEnd_(index << 1, m_root);
- int secondary_handle = getSecondaryFromInterval_(interval_handle);
- int right_end_handle = m_secondary_treaps.addElement((index << 1) + 1,
- secondary_handle);
- setRightEnd_(interval_handle, right_end_handle);
- m_interval_handles.set(index, interval_handle);
- m_c_count++;
- // assert(check_validation_());
+ return interval_handle;
}
- /**
- * Deletes the interval from the Interval_tree_impl. \param index The index
- * containing the interval to be deleted from the Interval_tree_impl.
- */
void remove(int index) {
if (!m_b_offline_dynamic || !m_b_construction_ended)
throw new GeometryException("invalid call");
@@ -531,8 +479,7 @@ void remove(int index) {
int interval_handle = m_interval_handles.get(index);
if (interval_handle == -1)
- throw new IllegalArgumentException(
- "the interval does not exist in the interval tree");
+ throw new GeometryException("the interval does not exist in the interval tree");
m_interval_handles.set(index, -1);
@@ -544,574 +491,595 @@ void remove(int index) {
int size;
int secondary_handle = getSecondaryFromInterval_(interval_handle);
- int primary_handle;
+ int tertiary_handle = -1;
- primary_handle = m_secondary_treaps.getTreapData(secondary_handle);
- m_secondary_treaps.deleteNode(getLeftEnd_(interval_handle),
- secondary_handle);
- m_secondary_treaps.deleteNode(getRightEnd_(interval_handle),
- secondary_handle);
+ tertiary_handle = m_secondary_treaps.getTreapData(secondary_handle);
+ m_secondary_treaps.deleteNode(getLeftEnd_(interval_handle), secondary_handle);
+ m_secondary_treaps.deleteNode(getRightEnd_(interval_handle), secondary_handle);
size = m_secondary_treaps.size(secondary_handle);
if (size == 0) {
m_secondary_treaps.deleteTreap(secondary_handle);
- setSecondaryToPrimary_(primary_handle, -1);
+ setSecondaryToTertiary_(tertiary_handle, -1);
}
m_interval_nodes.deleteElement(interval_handle);
- int tertiary_handle = getPPTR_(primary_handle);
- int lptr = getLPTR_(primary_handle);
- int rptr = getRPTR_(primary_handle);
+ int pptr = getPPTR_(tertiary_handle);
+ int lptr = getLPTR_(tertiary_handle);
+ int rptr = getRPTR_(tertiary_handle);
int iterations = 0;
- while (!(size > 0 || primary_handle == m_root || (lptr != -1 && rptr != -1))) {
+ while (!(size > 0 || tertiary_handle == m_root || (lptr != -1 && rptr != -1))) {
assert (size == 0);
assert (lptr == -1 || rptr == -1);
- assert (primary_handle != 0);
+ assert (tertiary_handle != 0);
- if (primary_handle == getLPTR_(tertiary_handle)) {
+ if (tertiary_handle == getLPTR_(pptr)) {
if (lptr != -1) {
- setLPTR_(tertiary_handle, lptr);
- setPPTR_(lptr, tertiary_handle);
- setLPTR_(primary_handle, -1);
- setPPTR_(primary_handle, -1);
+ setLPTR_(pptr, lptr);
+ setPPTR_(lptr, pptr);
+ setLPTR_(tertiary_handle, -1);
+ setPPTR_(tertiary_handle, -1);
} else if (rptr != -1) {
- setLPTR_(tertiary_handle, rptr);
- setPPTR_(rptr, tertiary_handle);
- setRPTR_(primary_handle, -1);
- setPPTR_(primary_handle, -1);
+ setLPTR_(pptr, rptr);
+ setPPTR_(rptr, pptr);
+ setRPTR_(tertiary_handle, -1);
+ setPPTR_(tertiary_handle, -1);
} else {
- setLPTR_(tertiary_handle, -1);
- setPPTR_(primary_handle, -1);
+ setLPTR_(pptr, -1);
+ setPPTR_(tertiary_handle, -1);
}
} else {
if (lptr != -1) {
- setRPTR_(tertiary_handle, lptr);
- setPPTR_(lptr, tertiary_handle);
- setLPTR_(primary_handle, -1);
- setPPTR_(primary_handle, -1);
+ setRPTR_(pptr, lptr);
+ setPPTR_(lptr, pptr);
+ setLPTR_(tertiary_handle, -1);
+ setPPTR_(tertiary_handle, -1);
} else if (rptr != -1) {
- setRPTR_(tertiary_handle, rptr);
- setPPTR_(rptr, tertiary_handle);
- setRPTR_(primary_handle, -1);
- setPPTR_(primary_handle, -1);
- } else {
+ setRPTR_(pptr, rptr);
+ setPPTR_(rptr, pptr);
setRPTR_(tertiary_handle, -1);
- setPPTR_(primary_handle, -1);
+ setPPTR_(tertiary_handle, -1);
+ } else {
+ setRPTR_(pptr, -1);
+ setPPTR_(tertiary_handle, -1);
}
}
+ m_tertiary_nodes.deleteElement(tertiary_handle);
+
iterations++;
- primary_handle = tertiary_handle;
- secondary_handle = getSecondaryFromPrimary(primary_handle);
- size = (secondary_handle != -1 ? m_secondary_treaps
- .size(secondary_handle) : 0);
- lptr = getLPTR_(primary_handle);
- rptr = getRPTR_(primary_handle);
- tertiary_handle = getPPTR_(primary_handle);
+ tertiary_handle = pptr;
+ secondary_handle = getSecondaryFromTertiary_(tertiary_handle);
+ size = (secondary_handle != -1 ? m_secondary_treaps.size(secondary_handle) : 0);
+ lptr = getLPTR_(tertiary_handle);
+ rptr = getRPTR_(tertiary_handle);
+ pptr = getPPTR_(tertiary_handle);
}
assert (iterations <= 2);
- // assert(check_validation_());
+ //assert(check_validation_());
}
- /*
- * Resets the Interval_tree_impl to an empty state, but maintains a handle
- * on the current intervals.
- */
- void reset() {
- if (!m_b_offline_dynamic || !m_b_construction_ended)
- throw new IllegalArgumentException("invalid call");
+ private void reset_(boolean b_new_intervals, boolean b_envelopes_ref) {
+ if (b_new_intervals) {
+ m_b_envelopes_ref = false;
+ m_envelopes_ref = null;
+
+ m_b_sort_intervals = true;
+ m_b_constructing = true;
+ m_b_construction_ended = false;
+
+ if (m_end_indices_unique == null)
+ m_end_indices_unique = (AttributeStreamOfInt32) (AttributeStreamBase.createIndexStream(0));
+ else
+ m_end_indices_unique.resize(0);
+
+ if (!b_envelopes_ref) {
+ if (m_intervals == null)
+ m_intervals = new ArrayList(0);
+ else
+ m_intervals.clear();
+ } else {
+ if (m_intervals != null)
+ m_intervals.clear();
+
+ m_b_envelopes_ref = true;
+ }
+ } else {
+ assert (m_b_offline_dynamic && m_b_construction_ended);
+ m_b_sort_intervals = false;
+ }
+
+ if (m_b_offline_dynamic) {
+ if (m_interval_handles == null) {
+ m_interval_handles = (AttributeStreamOfInt32) (AttributeStreamBase.createIndexStream(0));
+ m_secondary_treaps = new Treap();
+ m_secondary_treaps.setComparator(new SecondaryComparator(this));
+ } else {
+ m_secondary_treaps.clear();
+ }
+ } else {
+ if (m_secondary_lists == null)
+ m_secondary_lists = new IndexMultiDCList();
+ else
+ m_secondary_lists.clear();
+ }
+
+ if (m_tertiary_nodes == null) {
+ m_interval_nodes = new StridedIndexTypeCollection(3);
+ m_tertiary_nodes = new StridedIndexTypeCollection(m_b_offline_dynamic ? 5 : 4);
+ } else {
+ m_interval_nodes.deleteAll(false);
+ m_tertiary_nodes.deleteAll(false);
+ }
- reset_(false);
+ m_root = -1;
+ m_c_count = 0;
}
- /**
- * Returns the number of intervals stored in the Interval_tree_impl
- */
- int size() {
- return m_c_count;
+ private double getDiscriminant_(int tertiary_handle) {
+ int discriminant_index_1 = getDiscriminantIndex1_(tertiary_handle);
+ return getDiscriminantFromIndex1_(discriminant_index_1);
}
- /**
- * Gets an iterator on the Interval_tree_impl using the input Envelope_1D
- * interval as the query. To reuse the existing iterator on the same
- * Interval_tree_impl but with a new query, use the reset_iterator function
- * on the Interval_tree_iterator_impl. \param query The Envelope_1D interval
- * used for the query. \param tolerance The tolerance used for the
- * intersection tests.
- */
- IntervalTreeIteratorImpl getIterator(Envelope1D query, double tolerance) {
- return new IntervalTreeImpl.IntervalTreeIteratorImpl(this, query,
- tolerance);
- }
+ private double getDiscriminantFromIndex1_(int discriminant_index_1) {
+ if (discriminant_index_1 == -1)
+ return NumberUtils.NaN();
- /**
- * Gets an iterator on the Interval_tree_impl using the input double as the
- * stabbing query. To reuse the existing iterator on the same
- * Interval_tree_impl but with a new query, use the reset_iterator function
- * on the Interval_tree_iterator_impl. \param query The double used for the
- * stabbing query. \param tolerance The tolerance used for the intersection
- * tests.
- */
- IntervalTreeIteratorImpl getIterator(double query, double tolerance) {
- return new IntervalTreeImpl.IntervalTreeIteratorImpl(this, query,
- tolerance);
- }
+ if (discriminant_index_1 > 0) {
+ int j = discriminant_index_1 - 2;
+ int e_1 = m_end_indices_unique.get(j);
+ int e_2 = m_end_indices_unique.get(j + 1);
- /**
- * Gets an iterator on the Interval_tree_impl.
- */
- IntervalTreeIteratorImpl getIterator() {
- return new IntervalTreeImpl.IntervalTreeIteratorImpl(this);
- }
+ double v_1 = getValue_(e_1);
+ double v_2 = getValue_(e_2);
+ assert (v_1 < v_2);
- private static final class SecondaryComparator extends Treap.Comparator {
- SecondaryComparator(IntervalTreeImpl interval_tree) {
- m_interval_tree = interval_tree;
+ return 0.5 * (v_1 + v_2);
}
- @Override
- public int compare(Treap treap, int e_1, int node) {
- int e_2 = treap.getElement(node);
- double v_1 = m_interval_tree.getValue_(e_1);
- double v_2 = m_interval_tree.getValue_(e_2);
+ int j = -discriminant_index_1 - 2;
+ assert (j >= 0);
+ int e = m_end_indices_unique.get(j);
+ double v = getValue_(e);
- if (v_1 < v_2)
- return -1;
- if (v_1 == v_2) {
- if (isLeft_(e_1) && isRight_(e_2))
- return -1;
- if (isLeft_(e_2) && isRight_(e_1))
- return 1;
- return 0;
- }
- return 1;
+ return v;
+ }
+
+ private int calculateDiscriminantIndex1_(int il, int ir) {
+ int discriminant_index_1;
+
+ if (il < ir) {
+ int im = il + (ir - il) / 2;
+ discriminant_index_1 = im + 2; // positive discriminant means use average of im and im + 1
+ } else {
+ discriminant_index_1 = -(il + 2); // negative discriminant just means use il (-(il + 2) will never be -1)
}
+ return discriminant_index_1;
+ }
+
+ static final class IntervalTreeIteratorImpl {
+
private IntervalTreeImpl m_interval_tree;
- };
+ private Envelope1D m_query = new Envelope1D();
+ private int m_tertiary_handle;
+ private int m_next_tertiary_handle;
+ private int m_forked_handle;
+ private int m_current_end_handle;
+ private int m_next_end_handle;
+ private AttributeStreamOfInt32 m_tertiary_stack = new AttributeStreamOfInt32(0);
+ private int m_function_index;
+ private int[] m_function_stack = new int[2];
- private boolean m_b_offline_dynamic;
- private ArrayList m_intervals;
- private StridedIndexTypeCollection m_primary_nodes; // 8 elements for
- // offline dynamic case,
- // 7 elements for static
- // case
- private StridedIndexTypeCollection m_interval_nodes; // 3 elements
- private AttributeStreamOfInt32 m_interval_handles; // for offline dynamic
- // case
- private IndexMultiDCList m_secondary_lists; // for static case
- private Treap m_secondary_treaps; // for off-line dynamic case
- private AttributeStreamOfInt32 m_end_indices_unique; // for both offline
- // dynamic and
- // static cases
- private int m_c_count;
- private int m_root;
- private boolean m_b_sort_intervals;
- private boolean m_b_constructing;
- private boolean m_b_construction_ended;
+ private interface State {
+ static final int initialize = 0;
+ static final int pIn = 1;
+ static final int pL = 2;
+ static final int pR = 3;
+ static final int pT = 4;
+ static final int right = 5;
+ static final int left = 6;
+ static final int all = 7;
+ }
- private void querySortedEndPointIndices_(AttributeStreamOfInt32 end_indices) {
- int size = m_intervals.size();
+ private int getNext_() {
+ if (!m_interval_tree.m_b_offline_dynamic)
+ return m_interval_tree.m_secondary_lists.getNext(m_current_end_handle);
- for (int i = 0; i < 2 * size; i++)
- end_indices.add(i);
+ return m_interval_tree.m_secondary_treaps.getNext(m_current_end_handle);
+ }
- sortEndIndices_(end_indices, 0, 2 * size);
- }
+ private int getPrev_() {
+ if (!m_interval_tree.m_b_offline_dynamic)
+ return m_interval_tree.m_secondary_lists.getPrev(m_current_end_handle);
- private void querySortedDuplicatesRemoved_(
- AttributeStreamOfInt32 end_indices_sorted) {
- // remove duplicates
+ return m_interval_tree.m_secondary_treaps.getPrev(m_current_end_handle);
+ }
- double prev = NumberUtils.TheNaN;
- for (int i = 0; i < end_indices_sorted.size(); i++) {
- int e = end_indices_sorted.get(i);
- double v = getValue_(e);
+ private int getCurrentEndIndex_() {
+ if (!m_interval_tree.m_b_offline_dynamic)
+ return m_interval_tree.m_secondary_lists.getData(m_current_end_handle);
- if (v != prev) {
- m_end_indices_unique.add(e);
- prev = v;
- }
+ return m_interval_tree.m_secondary_treaps.getElement(m_current_end_handle);
}
- }
- private void insertIntervalsStatic_() {
- int size = m_intervals.size();
+ int next() {
+ if (!m_interval_tree.m_b_construction_ended)
+ throw new GeometryException("invalid call");
- assert (m_b_sort_intervals);
+ if (m_function_index < 0)
+ return -1;
- // sort
- AttributeStreamOfInt32 end_indices_sorted = new AttributeStreamOfInt32(
- 0);
- end_indices_sorted.reserve(2 * size);
- querySortedEndPointIndices_(end_indices_sorted);
+ boolean b_searching = true;
- // remove duplicates
- m_end_indices_unique.reserve(2 * size);
- m_end_indices_unique.resize(0);
- querySortedDuplicatesRemoved_(end_indices_sorted);
+ while (b_searching) {
+ switch (m_function_stack[m_function_index]) {
+ case State.pIn:
+ b_searching = pIn_();
+ break;
+ case State.pL:
+ b_searching = pL_();
+ break;
+ case State.pR:
+ b_searching = pR_();
+ break;
+ case State.pT:
+ b_searching = pT_();
+ break;
+ case State.right:
+ b_searching = right_();
+ break;
+ case State.left:
+ b_searching = left_();
+ break;
+ case State.all:
+ b_searching = all_();
+ break;
+ case State.initialize:
+ b_searching = initialize_();
+ break;
+ default:
+ throw GeometryException.GeometryInternalError();
+ }
+ }
- assert (m_primary_nodes.size() == 0);
- m_interval_nodes.setCapacity(size); // one for each interval being
- // inserted. each element contains a
- // primary node, a left secondary
- // node, and a right secondary node.
- m_secondary_lists.reserveNodes(2 * size); // one for each end point of
- // the original interval set
- // (not the unique set)
-
- AttributeStreamOfInt32 interval_handles = (AttributeStreamOfInt32) AttributeStreamBase
- .createIndexStream(size);
- interval_handles.setRange(-1, 0, size);
+ if (m_current_end_handle != -1)
+ return getCurrentEndIndex_() >> 1;
- m_root = createPrimaryNode_();
+ return -1;
+ }
- for (int i = 0; i < end_indices_sorted.size(); i++) {
- int e = end_indices_sorted.get(i);
- int interval_handle = interval_handles.get(e >> 1);
+ private boolean initialize_() {
+ m_tertiary_handle = -1;
+ m_next_tertiary_handle = -1;
+ m_forked_handle = -1;
+ m_current_end_handle = -1;
- if (interval_handle != -1) {// insert the right end point
- assert (isRight_(e));
- int secondary_handle = getSecondaryFromInterval_(interval_handle);
- setRightEnd_(interval_handle,
- m_secondary_lists.addElement(secondary_handle, e));
- } else {// insert the left end point
- assert (isLeft_(e));
- interval_handle = insertIntervalEnd_(e, m_root);
- interval_handles.set(e >> 1, interval_handle);
+ if (m_interval_tree.m_tertiary_nodes != null && m_interval_tree.m_tertiary_nodes.size() > 0) {
+ m_function_stack[0] = State.pIn; // overwrite initialize
+ m_next_tertiary_handle = m_interval_tree.m_root;
+ return true;
}
+
+ m_function_index = -1;
+ return false;
}
- assert (m_secondary_lists.getNodeCount() == 2 * size);
- }
+ private boolean pIn_() {
+ m_tertiary_handle = m_next_tertiary_handle;
- private int insertIntervalEnd_(int end_index, int root) {
- assert (isLeft_(end_index));
- int primary_handle = root;
- int tertiary_handle = root;
- int ptr = root;
- int secondary_handle;
- int interval_handle = -1;
- int il = 0, ir = m_end_indices_unique.size() - 1, im = 0;
- int index = end_index >> 1;
- double discriminant_tertiary = NumberUtils.TheNaN;
- double discriminant_ptr = NumberUtils.TheNaN;
- boolean bSearching = true;
+ if (m_tertiary_handle == -1) {
+ m_function_index = -1;
+ m_current_end_handle = -1;
+ return false;
+ }
- double min = getMin_(index);
- double max = getMax_(index);
+ double discriminant = m_interval_tree.getDiscriminant_(m_tertiary_handle);
- while (bSearching) {
- if (il < ir) {
- im = il + (ir - il) / 2;
+ if (m_query.vmax < discriminant) {
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
+ m_next_tertiary_handle = m_interval_tree.getLPTR_(m_tertiary_handle);
- if (getDiscriminantIndex1_(primary_handle) == -1)
- setDiscriminantIndices_(primary_handle,
- m_end_indices_unique.get(im),
- m_end_indices_unique.get(im + 1));
- } else {
- assert (il == ir);
- assert (min == max);
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
+ m_function_stack[++m_function_index] = State.left;
+ }
- if (getDiscriminantIndex1_(primary_handle) == -1)
- setDiscriminantIndices_(primary_handle,
- m_end_indices_unique.get(il),
- m_end_indices_unique.get(il));
+ return true;
}
- double discriminant = getDiscriminant_(primary_handle);
- assert (!NumberUtils.isNaN(discriminant));
+ if (discriminant < m_query.vmin) {
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
+ m_next_tertiary_handle = m_interval_tree.getRPTR_(m_tertiary_handle);
- if (max < discriminant) {
- if (ptr != -1) {
- if (ptr == primary_handle) {
- tertiary_handle = primary_handle;
- discriminant_tertiary = discriminant;
- ptr = getLPTR_(primary_handle);
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getLast_(secondary_handle);
+ m_function_stack[++m_function_index] = State.right;
+ }
- if (ptr != -1)
- discriminant_ptr = getDiscriminant_(ptr);
- else
- discriminant_ptr = NumberUtils.TheNaN;
- } else if (discriminant_ptr > discriminant) {
- if (discriminant < discriminant_tertiary)
- setLPTR_(tertiary_handle, primary_handle);
- else
- setRPTR_(tertiary_handle, primary_handle);
+ return true;
+ }
- setRPTR_(primary_handle, ptr);
+ assert (m_query.contains(discriminant));
- if (m_b_offline_dynamic) {
- setPPTR_(primary_handle, tertiary_handle);
- setPPTR_(ptr, primary_handle);
- }
+ m_function_stack[m_function_index] = State.pL; // overwrite pIn
+ m_forked_handle = m_tertiary_handle;
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
+ m_next_tertiary_handle = m_interval_tree.getLPTR_(m_tertiary_handle);
- tertiary_handle = primary_handle;
- discriminant_tertiary = discriminant;
- ptr = -1;
- discriminant_ptr = NumberUtils.TheNaN;
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
+ m_function_stack[++m_function_index] = State.all;
+ }
- assert (getLPTR_(primary_handle) == -1);
- assert (getRightPrimary_(primary_handle) != -1);
- }
- }
+ return true;
+ }
+
+ private boolean pL_() {
+ m_tertiary_handle = m_next_tertiary_handle;
+
+ if (m_tertiary_handle == -1) {
+ m_function_stack[m_function_index] = State.pR; // overwrite pL
+ m_next_tertiary_handle = m_interval_tree.getRPTR_(m_forked_handle);
+ return true;
+ }
+
+ double discriminant = m_interval_tree.getDiscriminant_(m_tertiary_handle);
- int left_handle = getLeftPrimary_(primary_handle);
+ if (discriminant < m_query.vmin) {
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
+ m_next_tertiary_handle = m_interval_tree.getRPTR_(m_tertiary_handle);
- if (left_handle == -1) {
- left_handle = createPrimaryNode_();
- setLeftPrimary_(primary_handle, left_handle);
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getLast_(secondary_handle);
+ m_function_stack[++m_function_index] = State.right;
}
- primary_handle = left_handle;
- ir = im;
+ return true;
+ }
- continue;
+ assert (m_query.contains(discriminant));
+
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
+ m_next_tertiary_handle = m_interval_tree.getLPTR_(m_tertiary_handle);
+
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
+ m_function_stack[++m_function_index] = State.all;
}
- if (min > discriminant) {
- if (ptr != -1) {
- if (ptr == primary_handle) {
- tertiary_handle = primary_handle;
- discriminant_tertiary = discriminant;
- ptr = getRPTR_(primary_handle);
+ int rptr = m_interval_tree.getRPTR_(m_tertiary_handle);
- if (ptr != -1)
- discriminant_ptr = getDiscriminant_(ptr);
- else
- discriminant_ptr = NumberUtils.TheNaN;
- } else if (discriminant_ptr < discriminant) {
- if (discriminant < discriminant_tertiary)
- setLPTR_(tertiary_handle, primary_handle);
- else
- setRPTR_(tertiary_handle, primary_handle);
+ if (rptr != -1) {
+ m_tertiary_stack.add(rptr); // we'll search this in the pT state
+ }
- setLPTR_(primary_handle, ptr);
+ return true;
+ }
- if (m_b_offline_dynamic) {
- setPPTR_(primary_handle, tertiary_handle);
- setPPTR_(ptr, primary_handle);
- }
+ private boolean pR_() {
+ m_tertiary_handle = m_next_tertiary_handle;
- tertiary_handle = primary_handle;
- discriminant_tertiary = discriminant;
- ptr = -1;
- discriminant_ptr = NumberUtils.TheNaN;
+ if (m_tertiary_handle == -1) {
+ m_function_stack[m_function_index] = State.pT; // overwrite pR
+ return true;
+ }
- assert (getRPTR_(primary_handle) == -1);
- assert (getLeftPrimary_(primary_handle) != -1);
- }
- }
+ double discriminant = m_interval_tree.getDiscriminant_(m_tertiary_handle);
- int right_handle = getRightPrimary_(primary_handle);
+ if (m_query.vmax < discriminant) {
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
+ m_next_tertiary_handle = m_interval_tree.getLPTR_(m_tertiary_handle);
- if (right_handle == -1) {
- right_handle = createPrimaryNode_();
- setRightPrimary_(primary_handle, right_handle);
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
+ m_function_stack[++m_function_index] = State.left;
}
- primary_handle = right_handle;
- il = im + 1;
-
- continue;
+ return true;
}
- secondary_handle = getSecondaryFromPrimary(primary_handle);
+ assert (m_query.contains(discriminant));
- if (secondary_handle == -1) {
- secondary_handle = createSecondary_(primary_handle);
- setSecondaryToPrimary_(primary_handle, secondary_handle);
- }
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
- int left_end_handle = addEndIndex(secondary_handle, end_index);
- interval_handle = createIntervalNode_();
- setSecondaryToInterval_(interval_handle, secondary_handle);
- setLeftEnd_(interval_handle, left_end_handle);
+ m_next_tertiary_handle = m_interval_tree.getRPTR_(m_tertiary_handle);
- if (primary_handle != ptr) {
- assert (primary_handle != -1);
- assert (getLPTR_(primary_handle) == -1
- && getRPTR_(primary_handle) == -1 && (!m_b_offline_dynamic || getPPTR_(primary_handle) == -1));
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
+ m_function_stack[++m_function_index] = State.all;
+ }
- if (discriminant < discriminant_tertiary)
- setLPTR_(tertiary_handle, primary_handle);
- else
- setRPTR_(tertiary_handle, primary_handle);
+ int lptr = m_interval_tree.getLPTR_(m_tertiary_handle);
- if (m_b_offline_dynamic)
- setPPTR_(primary_handle, tertiary_handle);
+ if (lptr != -1) {
+ m_tertiary_stack.add(lptr); // we'll search this in the pT state
+ }
- if (ptr != -1) {
- if (discriminant_ptr < discriminant)
- setLPTR_(primary_handle, ptr);
- else
- setRPTR_(primary_handle, ptr);
+ return true;
+ }
- if (m_b_offline_dynamic)
- setPPTR_(ptr, primary_handle);
- }
+ private boolean pT_() {
+ if (m_tertiary_stack.size() == 0) {
+ m_function_index = -1;
+ m_current_end_handle = -1;
+ return false;
}
- bSearching = false;
- }
+ m_tertiary_handle = m_tertiary_stack.get(m_tertiary_stack.size() - 1);
+ m_tertiary_stack.resize(m_tertiary_stack.size() - 1);
- return interval_handle;
- }
+ int secondary_handle = m_interval_tree.getSecondaryFromTertiary_(m_tertiary_handle);
- private int createPrimaryNode_() {
- return m_primary_nodes.newElement();
- }
+ if (secondary_handle != -1) {
+ m_next_end_handle = m_interval_tree.getFirst_(secondary_handle);
+ m_function_stack[++m_function_index] = State.all;
+ }
- private int createSecondary_(int primary_handle) {
- if (!m_b_offline_dynamic)
- return m_secondary_lists.createList(primary_handle);
+ if (m_interval_tree.getLPTR_(m_tertiary_handle) != -1)
+ m_tertiary_stack.add(m_interval_tree.getLPTR_(m_tertiary_handle));
- return m_secondary_treaps.createTreap(primary_handle);
- }
+ if (m_interval_tree.getRPTR_(m_tertiary_handle) != -1)
+ m_tertiary_stack.add(m_interval_tree.getRPTR_(m_tertiary_handle));
- private int createIntervalNode_() {
- return m_interval_nodes.newElement();
- }
+ return true;
+ }
- private void reset_(boolean b_new_intervals) {
- if (b_new_intervals) {
- m_b_sort_intervals = true;
- m_b_constructing = true;
- m_b_construction_ended = false;
+ private boolean left_() {
+ m_current_end_handle = m_next_end_handle;
- if (m_end_indices_unique == null)
- m_end_indices_unique = (AttributeStreamOfInt32) (AttributeStreamBase
- .createIndexStream(0));
- else
- m_end_indices_unique.resize(0);
+ if (m_current_end_handle != -1 && IntervalTreeImpl.isLeft_(getCurrentEndIndex_()) && m_interval_tree.getValue_(getCurrentEndIndex_()) <= m_query.vmax) {
+ m_next_end_handle = getNext_();
+ return false;
+ }
- if (m_intervals == null)
- m_intervals = new ArrayList(0);
- else
- m_intervals.clear();
- } else {
- assert (m_b_offline_dynamic && m_b_construction_ended);
- m_b_sort_intervals = false;
+ m_function_index--;
+ return true;
}
- if (m_b_offline_dynamic) {
- if (m_interval_handles == null) {
- m_interval_handles = (AttributeStreamOfInt32) (AttributeStreamBase
- .createIndexStream(0));
- m_secondary_treaps = new Treap();
- m_secondary_treaps.setComparator(new SecondaryComparator(this));
- } else {
- m_secondary_treaps.clear();
+ private boolean right_() {
+ m_current_end_handle = m_next_end_handle;
+
+ if (m_current_end_handle != -1 && IntervalTreeImpl.isRight_(getCurrentEndIndex_()) && m_interval_tree.getValue_(getCurrentEndIndex_()) >= m_query.vmin) {
+ m_next_end_handle = getPrev_();
+ return false;
}
- } else {
- if (m_secondary_lists == null)
- m_secondary_lists = new IndexMultiDCList();
- else
- m_secondary_lists.clear();
- }
- if (m_primary_nodes == null) {
- m_interval_nodes = new StridedIndexTypeCollection(3);
- m_primary_nodes = new StridedIndexTypeCollection(
- m_b_offline_dynamic ? 8 : 7);
- } else {
- m_interval_nodes.deleteAll(false);
- m_primary_nodes.deleteAll(false);
+ m_function_index--;
+ return true;
}
- m_root = -1;
- m_c_count = 0;
- }
-
- private void setDiscriminantIndices_(int primary_handle, int e_1, int e_2) {
- setDiscriminantIndex1_(primary_handle, e_1);
- setDiscriminantIndex2_(primary_handle, e_2);
- }
+ private boolean all_() {
+ m_current_end_handle = m_next_end_handle;
- private double getDiscriminant_(int primary_handle) {
- int e_1 = getDiscriminantIndex1_(primary_handle);
- if (e_1 == -1)
- return NumberUtils.TheNaN;
+ if (m_current_end_handle != -1 && IntervalTreeImpl.isLeft_(getCurrentEndIndex_())) {
+ m_next_end_handle = getNext_();
+ return false;
+ }
- int e_2 = getDiscriminantIndex2_(primary_handle);
- assert (e_2 != -1);
+ m_function_index--;
+ return true;
+ }
- double v_1 = getValue_(e_1);
- double v_2 = getValue_(e_2);
+ IntervalTreeIteratorImpl(IntervalTreeImpl interval_tree, Envelope1D query, double tolerance) {
+ m_interval_tree = interval_tree;
+ m_tertiary_stack.reserve(20);
+ resetIterator(query, tolerance);
+ }
- if (v_1 == v_2)
- return v_1;
+ IntervalTreeIteratorImpl(IntervalTreeImpl interval_tree, double query, double tolerance) {
+ m_interval_tree = interval_tree;
+ m_tertiary_stack.reserve(20);
+ resetIterator(query, tolerance);
+ }
- return 0.5 * (v_1 + v_2);
- }
+ IntervalTreeIteratorImpl(IntervalTreeImpl interval_tree) {
+ m_interval_tree = interval_tree;
+ m_tertiary_stack.reserve(20);
+ m_function_index = -1;
+ }
- private boolean isActive_(int primary_handle) {
- int secondary_handle = getSecondaryFromPrimary(primary_handle);
+ void resetIterator(Envelope1D query, double tolerance) {
+ m_query.vmin = query.vmin - tolerance;
+ m_query.vmax = query.vmax + tolerance;
+ m_tertiary_stack.resize(0);
+ m_function_index = 0;
+ m_function_stack[0] = State.initialize;
+ }
- if (secondary_handle != -1)
- return true;
+ void resetIterator(double query_min, double query_max, double tolerance) {
+ m_query.vmin = query_min - tolerance;
+ m_query.vmax = query_max + tolerance;
+ m_tertiary_stack.resize(0);
+ m_function_index = 0;
+ m_function_stack[0] = State.initialize;
+ }
- int left_handle = getLeftPrimary_(primary_handle);
+ void resetIterator(double query, double tolerance) {
+ m_query.vmin = query - tolerance;
+ m_query.vmax = query + tolerance;
+ m_tertiary_stack.resize(0);
+ m_function_index = 0;
+ m_function_stack[0] = State.initialize;
+ }
+ }
- if (left_handle == -1)
- return false;
+ private static final class SecondaryComparator extends Treap.Comparator {
+ SecondaryComparator(IntervalTreeImpl interval_tree) {
+ m_interval_tree = interval_tree;
+ }
- int right_handle = getRightPrimary_(primary_handle);
+ @Override
+ public int compare(Treap treap, int e_1, int node) {
+ int e_2 = treap.getElement(node);
+ double v_1 = m_interval_tree.getValue_(e_1);
+ double v_2 = m_interval_tree.getValue_(e_2);
- if (right_handle == -1)
- return false;
+ if (v_1 < v_2)
+ return -1;
+ if (v_1 == v_2) {
+ if (isLeft_(e_1) && isRight_(e_2))
+ return -1;
+ if (isLeft_(e_2) && isRight_(e_1))
+ return 1;
+ return 0;
+ }
+ return 1;
+ }
- return true;
+ private IntervalTreeImpl m_interval_tree;
}
- private void setDiscriminantIndex1_(int primary_handle, int end_index) {
- m_primary_nodes.setField(primary_handle, 0, end_index);
+ private int createTertiaryNode_(int discriminant_index_1) {
+ int tertiary_handle = m_tertiary_nodes.newElement();
+ setDiscriminantIndex1_(tertiary_handle, discriminant_index_1);
+ return tertiary_handle;
}
- private void setDiscriminantIndex2_(int primary_handle, int end_index) {
- m_primary_nodes.setField(primary_handle, 1, end_index);
+ private int createSecondary_(int tertiary_handle) {
+ if (!m_b_offline_dynamic)
+ return m_secondary_lists.createList(tertiary_handle);
+
+ return m_secondary_treaps.createTreap(tertiary_handle);
}
- private void setLeftPrimary_(int primary_handle, int left_handle) {
- m_primary_nodes.setField(primary_handle, 3, left_handle);
+ private int createIntervalNode_() {
+ return m_interval_nodes.newElement();
}
- private void setRightPrimary_(int primary_handle, int right_handle) {
- m_primary_nodes.setField(primary_handle, 4, right_handle);
+ private void setDiscriminantIndex1_(int tertiary_handle, int end_index) {
+ m_tertiary_nodes.setField(tertiary_handle, 0, end_index);
}
- private void setSecondaryToPrimary_(int primary_handle, int secondary_handle) {
- m_primary_nodes.setField(primary_handle, 2, secondary_handle);
+ private void setSecondaryToTertiary_(int tertiary_handle, int secondary_handle) {
+ m_tertiary_nodes.setField(tertiary_handle, 1, secondary_handle);
}
- private void setLPTR_(int primary_handle, int lptr) {
- m_primary_nodes.setField(primary_handle, 5, lptr);
+ private void setLPTR_(int tertiary_handle, int lptr) {
+ m_tertiary_nodes.setField(tertiary_handle, 2, lptr);
}
- private void setRPTR_(int primary_handle, int rptr) {
- m_primary_nodes.setField(primary_handle, 6, rptr);
+ private void setRPTR_(int tertiary_handle, int rptr) {
+ m_tertiary_nodes.setField(tertiary_handle, 3, rptr);
}
- private void setPPTR_(int primary_handle, int pptr) {
- m_primary_nodes.setField(primary_handle, 7, pptr);
+ private void setPPTR_(int tertiary_handle, int pptr) {
+ m_tertiary_nodes.setField(tertiary_handle, 4, pptr);
}
- private void setSecondaryToInterval_(int interval_handle,
- int secondary_handle) {
+ private void setSecondaryToInterval_(int interval_handle, int secondary_handle) {
m_interval_nodes.setField(interval_handle, 0, secondary_handle);
}
- private int addEndIndex(int secondary_handle, int end_index) {
+ private int addEndIndex_(int secondary_handle, int end_index) {
int end_index_handle;
if (!m_b_offline_dynamic)
- end_index_handle = m_secondary_lists.addElement(secondary_handle,
- end_index);
+ end_index_handle = m_secondary_lists.addElement(secondary_handle, end_index);
else
- end_index_handle = m_secondary_treaps.addElement(end_index,
- secondary_handle);
+ end_index_handle = m_secondary_treaps.addElement(end_index, secondary_handle);
return end_index_handle;
}
@@ -1124,58 +1092,24 @@ private void setRightEnd_(int interval_handle, int right_end_handle) {
m_interval_nodes.setField(interval_handle, 2, right_end_handle);
}
- private int getFirst_(int secondary_handle) {
- if (!m_b_offline_dynamic)
- return m_secondary_lists.getFirst(secondary_handle);
-
- return m_secondary_treaps.getFirst(secondary_handle);
- }
-
- private int getLast_(int secondary_handle) {
- if (!m_b_offline_dynamic)
- return m_secondary_lists.getLast(secondary_handle);
-
- return m_secondary_treaps.getLast(secondary_handle);
- }
-
- private static boolean isLeft_(int end_index) {
- return (end_index & 0x1) == 0;
- }
-
- private static boolean isRight_(int end_index) {
- return (end_index & 0x1) == 1;
- }
-
- private int getDiscriminantIndex1_(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 0);
- }
-
- private int getDiscriminantIndex2_(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 1);
- }
-
- private int getSecondaryFromPrimary(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 2);
- }
-
- private int getLeftPrimary_(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 3);
+ private int getDiscriminantIndex1_(int tertiary_handle) {
+ return m_tertiary_nodes.getField(tertiary_handle, 0);
}
- private int getRightPrimary_(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 4);
+ private int getSecondaryFromTertiary_(int tertiary_handle) {
+ return m_tertiary_nodes.getField(tertiary_handle, 1);
}
- private int getLPTR_(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 5);
+ private int getLPTR_(int tertiary_handle) {
+ return m_tertiary_nodes.getField(tertiary_handle, 2);
}
- private int getRPTR_(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 6);
+ private int getRPTR_(int tertiary_handle) {
+ return m_tertiary_nodes.getField(tertiary_handle, 3);
}
- private int getPPTR_(int primary_handle) {
- return m_primary_nodes.getField(primary_handle, 7);
+ private int getPPTR_(int tertiary_handle) {
+ return m_tertiary_nodes.getField(tertiary_handle, 4);
}
private int getSecondaryFromInterval_(int interval_handle) {
@@ -1191,76 +1125,32 @@ private int getRightEnd_(int interval_handle) {
}
private double getMin_(int i) {
- Envelope1D interval = m_intervals.get(i);
- return interval.vmin;
+ return (!m_b_envelopes_ref ? m_intervals.get(i).vmin : m_envelopes_ref.get(i).xmin);
}
private double getMax_(int i) {
- Envelope1D interval = m_intervals.get(i);
- return interval.vmax;
+ return (!m_b_envelopes_ref ? m_intervals.get(i).vmax : m_envelopes_ref.get(i).xmax);
}
- // *********** Helpers for Bucket sort**************
- private BucketSort m_bucket_sort;
-
- private void sortEndIndices_(AttributeStreamOfInt32 end_indices,
- int begin_, int end_) {
- if (m_bucket_sort == null)
- m_bucket_sort = new BucketSort();
+ private int getFirst_(int secondary_handle) {
+ if (!m_b_offline_dynamic)
+ return m_secondary_lists.getFirst(secondary_handle);
- IntervalTreeBucketSortHelper sorter = new IntervalTreeBucketSortHelper(
- this);
- m_bucket_sort.sort(end_indices, begin_, end_, sorter);
+ return m_secondary_treaps.getFirst(secondary_handle);
}
- private void sortEndIndicesHelper_(AttributeStreamOfInt32 end_indices,
- int begin_, int end_) {
- end_indices.Sort(begin_, end_, new EndPointsComparer(this));
- }
+ private int getLast_(int secondary_handle) {
+ if (!m_b_offline_dynamic)
+ return m_secondary_lists.getLast(secondary_handle);
- private double getValue_(int e) {
- Envelope1D interval = m_intervals.get(e >> 1);
- double v = (isLeft_(e) ? interval.vmin : interval.vmax);
- return v;
+ return m_secondary_treaps.getLast(secondary_handle);
}
- private static final class EndPointsComparer extends
- AttributeStreamOfInt32.IntComparator { // For user sort
- EndPointsComparer(IntervalTreeImpl interval_tree) {
- m_interval_tree = interval_tree;
- }
-
- @Override
- public int compare(int e_1, int e_2) {
- double v_1 = m_interval_tree.getValue_(e_1);
- double v_2 = m_interval_tree.getValue_(e_2);
-
- if (v_1 < v_2 || (v_1 == v_2 && isLeft_(e_1) && isRight_(e_2)))
- return -1;
-
- return 1;
- }
-
- private IntervalTreeImpl m_interval_tree;
+ private static boolean isLeft_(int end_index) {
+ return (end_index & 0x1) == 0;
}
- private class IntervalTreeBucketSortHelper extends ClassicSort { // For
- // bucket
- // sort
- IntervalTreeBucketSortHelper(IntervalTreeImpl interval_tree) {
- m_interval_tree = interval_tree;
- }
-
- @Override
- public void userSort(int begin, int end, AttributeStreamOfInt32 indices) {
- m_interval_tree.sortEndIndicesHelper_(indices, begin, end);
- }
-
- @Override
- public double getValue(int e) {
- return m_interval_tree.getValue_(e);
- }
-
- private IntervalTreeImpl m_interval_tree;
+ private static boolean isRight_(int end_index) {
+ return (end_index & 0x1) == 1;
}
}
diff --git a/src/com/esri/core/geometry/JSONUtils.java b/src/main/java/com/esri/core/geometry/JSONUtils.java
similarity index 52%
rename from src/com/esri/core/geometry/JSONUtils.java
rename to src/main/java/com/esri/core/geometry/JSONUtils.java
index e401df70..14bcf142 100644
--- a/src/com/esri/core/geometry/JSONUtils.java
+++ b/src/main/java/com/esri/core/geometry/JSONUtils.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,28 +23,22 @@
*/
package com.esri.core.geometry;
-import java.io.IOException;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-
final class JSONUtils {
- static boolean isObjectStart(JsonParser parser) throws Exception {
- return parser.getCurrentToken() == null ? parser.nextToken() == JsonToken.START_OBJECT
- : parser.getCurrentToken() == JsonToken.START_OBJECT;
+ static boolean isObjectStart(JsonReader parser) throws Exception {
+ return parser.currentToken() == null ? parser.nextToken() == JsonReader.Token.START_OBJECT
+ : parser.currentToken() == JsonReader.Token.START_OBJECT;
}
- static double readDouble(JsonParser parser) throws JsonParseException,
- IOException, Exception {
- if (parser.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT)
- return parser.getDoubleValue();
- else if (parser.getCurrentToken() == JsonToken.VALUE_NUMBER_INT)
- return parser.getIntValue();
- else if (parser.getCurrentToken() == JsonToken.VALUE_NULL)
+ static double readDouble(JsonReader parser) {
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_FLOAT)
+ return parser.currentDoubleValue();
+ else if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
+ return parser.currentIntValue();
+ else if (parser.currentToken() == JsonReader.Token.VALUE_NULL)
return NumberUtils.NaN();
- else if (parser.getCurrentToken() == JsonToken.VALUE_STRING)
- if (parser.getText().equals("NaN"))
+ else if (parser.currentToken() == JsonReader.Token.VALUE_STRING)
+ if (parser.currentString().equals("NaN"))
return NumberUtils.NaN();
throw new GeometryException("invalid parameter");
diff --git a/src/com/esri/core/geometry/JsonCursor.java b/src/main/java/com/esri/core/geometry/JsonCursor.java
similarity index 95%
rename from src/com/esri/core/geometry/JsonCursor.java
rename to src/main/java/com/esri/core/geometry/JsonCursor.java
index eba7987d..0af0024f 100644
--- a/src/com/esri/core/geometry/JsonCursor.java
+++ b/src/main/java/com/esri/core/geometry/JsonCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
/**
* An abstract Json String Cursor class.
*/
-abstract class JsonCursor {
+public abstract class JsonCursor {
/**
* Moves the cursor to the next string. Returns null when reached the end.
diff --git a/src/main/java/com/esri/core/geometry/JsonGeometryException.java b/src/main/java/com/esri/core/geometry/JsonGeometryException.java
new file mode 100644
index 00000000..7402e0de
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/JsonGeometryException.java
@@ -0,0 +1,54 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+/**
+ * A runtime exception raised when a JSON related exception occurs.
+ */
+public class JsonGeometryException extends GeometryException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a Json Geometry Exception with the given error string/message.
+ *
+ * @param str
+ * - The error string.
+ */
+ public JsonGeometryException(String str) {
+ super(str);
+ }
+
+ /**
+ * Constructs a Json Geometry Exception with the given another exception.
+ *
+ * @param ex
+ * - The exception to copy the message from.
+ */
+ public JsonGeometryException(Exception ex) {
+ super(ex.getMessage());
+ }
+
+}
+
diff --git a/src/main/java/com/esri/core/geometry/JsonParserReader.java b/src/main/java/com/esri/core/geometry/JsonParserReader.java
new file mode 100644
index 00000000..90427c63
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/JsonParserReader.java
@@ -0,0 +1,171 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import com.fasterxml.jackson.core.*;
+
+/**
+ * A throw in JsonReader built around the Jackson JsonParser.
+ *
+ */
+public class JsonParserReader implements JsonReader {
+
+ private JsonParser m_jsonParser;
+
+ public JsonParserReader(JsonParser jsonParser) {
+ m_jsonParser = jsonParser;
+ }
+
+ /**
+ * Creates a JsonReader for the string.
+ * The nextToken is called by this method.
+ */
+ public static JsonReader createFromString(String str) {
+ try {
+ JsonFactory factory = new JsonFactory();
+ JsonParser jsonParser = factory.createParser(str);
+
+ jsonParser.nextToken();
+ return new JsonParserReader(jsonParser);
+ }
+ catch (Exception ex) {
+ throw new JsonGeometryException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Creates a JsonReader for the string.
+ * The nextToken is not called by this method.
+ */
+ public static JsonReader createFromStringNNT(String str) {
+ try {
+ JsonFactory factory = new JsonFactory();
+ JsonParser jsonParser = factory.createParser(str);
+
+ return new JsonParserReader(jsonParser);
+ }
+ catch (Exception ex) {
+ throw new JsonGeometryException(ex.getMessage());
+ }
+ }
+
+ private static Token mapToken(JsonToken token) {
+ if (token == JsonToken.END_ARRAY)
+ return Token.END_ARRAY;
+ if (token == JsonToken.END_OBJECT)
+ return Token.END_OBJECT;
+ if (token == JsonToken.FIELD_NAME)
+ return Token.FIELD_NAME;
+ if (token == JsonToken.START_ARRAY)
+ return Token.START_ARRAY;
+ if (token == JsonToken.START_OBJECT)
+ return Token.START_OBJECT;
+ if (token == JsonToken.VALUE_FALSE)
+ return Token.VALUE_FALSE;
+ if (token == JsonToken.VALUE_NULL)
+ return Token.VALUE_NULL;
+ if (token == JsonToken.VALUE_NUMBER_FLOAT)
+ return Token.VALUE_NUMBER_FLOAT;
+ if (token == JsonToken.VALUE_NUMBER_INT)
+ return Token.VALUE_NUMBER_INT;
+ if (token == JsonToken.VALUE_STRING)
+ return Token.VALUE_STRING;
+ if (token == JsonToken.VALUE_TRUE)
+ return Token.VALUE_TRUE;
+ if (token == null)
+ return null;
+
+ throw new JsonGeometryException("unexpected token");
+ }
+
+ @Override
+ public Token nextToken() throws JsonGeometryException {
+ try {
+ JsonToken token = m_jsonParser.nextToken();
+ return mapToken(token);
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+ }
+
+ @Override
+ public Token currentToken() throws JsonGeometryException {
+ try {
+ return mapToken(m_jsonParser.getCurrentToken());
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+ }
+
+ @Override
+ public void skipChildren() throws JsonGeometryException {
+ try {
+ m_jsonParser.skipChildren();
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+
+ }
+
+ @Override
+ public String currentString() throws JsonGeometryException {
+ try {
+ return m_jsonParser.getText();
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+
+ }
+
+ @Override
+ public double currentDoubleValue() throws JsonGeometryException {
+ try {
+ return m_jsonParser.getValueAsDouble();
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+
+ }
+
+ @Override
+ public int currentIntValue() throws JsonGeometryException {
+ try {
+ return m_jsonParser.getValueAsInt();
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+ }
+
+ @Override
+ public boolean currentBooleanValue() {
+ Token t = currentToken();
+ if (t == Token.VALUE_TRUE)
+ return true;
+ else if (t == Token.VALUE_FALSE)
+ return false;
+ throw new JsonGeometryException("Not a boolean");
+ }
+}
+
diff --git a/src/main/java/com/esri/core/geometry/JsonReader.java b/src/main/java/com/esri/core/geometry/JsonReader.java
new file mode 100644
index 00000000..541143e3
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/JsonReader.java
@@ -0,0 +1,60 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+/**
+ * An abstract reader for Json.
+ *
+ * See JsonParserReader for a concrete implementation around JsonParser.
+ */
+abstract public interface JsonReader {
+ public static enum Token {
+ END_ARRAY,
+ END_OBJECT,
+ FIELD_NAME,
+ START_ARRAY,
+ START_OBJECT,
+ VALUE_FALSE,
+ VALUE_NULL,
+ VALUE_NUMBER_FLOAT,
+ VALUE_NUMBER_INT,
+ VALUE_STRING,
+ VALUE_TRUE
+ }
+
+ abstract public Token nextToken() throws JsonGeometryException;
+
+ abstract public Token currentToken() throws JsonGeometryException;
+
+ abstract public void skipChildren() throws JsonGeometryException;
+
+ abstract public String currentString() throws JsonGeometryException;
+
+ abstract public double currentDoubleValue() throws JsonGeometryException;
+
+ abstract public int currentIntValue() throws JsonGeometryException;
+
+ abstract public boolean currentBooleanValue() throws JsonGeometryException;
+}
+
diff --git a/src/com/esri/core/geometry/JsonParserCursor.java b/src/main/java/com/esri/core/geometry/JsonReaderCursor.java
similarity index 83%
rename from src/com/esri/core/geometry/JsonParserCursor.java
rename to src/main/java/com/esri/core/geometry/JsonReaderCursor.java
index fe3605ab..8e0f16de 100644
--- a/src/com/esri/core/geometry/JsonParserCursor.java
+++ b/src/main/java/com/esri/core/geometry/JsonReaderCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,20 +21,19 @@
email: contracts@esri.com
*/
-package com.esri.core.geometry;
-import org.codehaus.jackson.JsonParser;
+package com.esri.core.geometry;
/**
- * An abstract JsonParser Cursor class.
+ * An abstract JsonReader Cursor class.
*/
-abstract class JsonParserCursor {
+abstract class JsonReaderCursor {
/**
- * Moves the cursor to the next JsonParser. Returns null when reached the
+ * Moves the cursor to the next JsonReader. Returns null when reached the
* end.
*/
- public abstract JsonParser next();
+ public abstract JsonReader next();
/**
* Returns the ID of the current geometry. The ID is propagated across the
diff --git a/src/main/java/com/esri/core/geometry/JsonStringWriter.java b/src/main/java/com/esri/core/geometry/JsonStringWriter.java
new file mode 100644
index 00000000..a8df0930
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/JsonStringWriter.java
@@ -0,0 +1,426 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+final class JsonStringWriter extends JsonWriter {
+
+ @Override
+ Object getJson() {
+ next_(Action.accept);
+ return m_jsonString.toString();
+ }
+
+ @Override
+ void startObject() {
+ next_(Action.addObject);
+ m_jsonString.append('{');
+ m_functionStack.add(State.objectStart);
+ }
+
+ @Override
+ void startArray() {
+ next_(Action.addArray);
+ m_jsonString.append('[');
+ m_functionStack.add(State.arrayStart);
+ }
+
+ @Override
+ void endObject() {
+ next_(Action.popObject);
+ m_jsonString.append('}');
+ }
+
+ @Override
+ void endArray() {
+ next_(Action.popArray);
+ m_jsonString.append(']');
+ }
+
+ @Override
+ void addFieldName(String fieldName) {
+ next_(Action.addKey);
+ appendQuote_(fieldName);
+ }
+
+ @Override
+ void addPairObject(String fieldName) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueObject_();
+ }
+
+ @Override
+ void addPairArray(String fieldName) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueArray_();
+ }
+
+ @Override
+ void addPairString(String fieldName, String v) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueString_(v);
+ }
+
+ @Override
+ void addPairDouble(String fieldName, double v) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueDouble_(v);
+ }
+
+ @Override
+ void addPairDouble(String fieldName, double v, int precision, boolean bFixedPoint) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueDouble_(v, precision, bFixedPoint);
+ }
+
+ @Override
+ void addPairInt(String fieldName, int v) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueInt_(v);
+ }
+
+ @Override
+ void addPairBoolean(String fieldName, boolean v) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueBoolean_(v);
+ }
+
+ @Override
+ void addPairNull(String fieldName) {
+ next_(Action.addPair);
+ appendQuote_(fieldName);
+ m_jsonString.append(":");
+ addValueNull_();
+ }
+
+ @Override
+ void addValueObject() {
+ next_(Action.addObject);
+ addValueObject_();
+ }
+
+ @Override
+ void addValueArray() {
+ next_(Action.addArray);
+ addValueArray_();
+ }
+
+ @Override
+ void addValueString(String v) {
+ next_(Action.addTerminal);
+ addValueString_(v);
+ }
+
+ @Override
+ void addValueDouble(double v) {
+ next_(Action.addTerminal);
+ addValueDouble_(v);
+ }
+
+ @Override
+ void addValueDouble(double v, int precision, boolean bFixedPoint) {
+ next_(Action.addTerminal);
+ addValueDouble_(v, precision, bFixedPoint);
+ }
+
+ @Override
+ void addValueInt(int v) {
+ next_(Action.addTerminal);
+ addValueInt_(v);
+ }
+
+ @Override
+ void addValueBoolean(boolean v) {
+ next_(Action.addTerminal);
+ addValueBoolean_(v);
+ }
+
+ @Override
+ void addValueNull() {
+ next_(Action.addTerminal);
+ addValueNull_();
+ }
+
+ JsonStringWriter() {
+ m_jsonString = new StringBuilder();
+ m_functionStack = new AttributeStreamOfInt32(0);
+ m_functionStack.add(State.accept);
+ m_functionStack.add(State.start);
+ }
+
+ private StringBuilder m_jsonString;
+ private AttributeStreamOfInt32 m_functionStack;
+
+ private void addValueObject_() {
+ m_jsonString.append('{');
+ m_functionStack.add(State.objectStart);
+ }
+
+ private void addValueArray_() {
+ m_jsonString.append('[');
+ m_functionStack.add(State.arrayStart);
+ }
+
+ private void addValueString_(String v) {
+ appendQuote_(v);
+ }
+
+ private void addValueDouble_(double v) {
+ if (NumberUtils.isNaN(v)) {
+ addValueNull_();
+ return;
+ }
+
+ StringUtils.appendDouble(v, 17, m_jsonString);
+ }
+
+ private void addValueDouble_(double v, int precision, boolean bFixedPoint) {
+ if (NumberUtils.isNaN(v)) {
+ addValueNull_();
+ return;
+ }
+
+ if (bFixedPoint)
+ StringUtils.appendDoubleF(v, precision, m_jsonString);
+ else
+ StringUtils.appendDouble(v, precision, m_jsonString);
+ }
+
+ private void addValueInt_(int v) {
+ m_jsonString.append(v);
+ }
+
+ private void addValueBoolean_(boolean v) {
+ if (v) {
+ m_jsonString.append("true");
+ } else {
+ m_jsonString.append("false");
+ }
+ }
+
+ private void addValueNull_() {
+ m_jsonString.append("null");
+ }
+
+ private void next_(int action) {
+ switch (m_functionStack.getLast()) {
+ case State.accept:
+ accept_(action);
+ break;
+ case State.start:
+ start_(action);
+ break;
+ case State.objectStart:
+ objectStart_(action);
+ break;
+ case State.arrayStart:
+ arrayStart_(action);
+ break;
+ case State.pairEnd:
+ pairEnd_(action);
+ break;
+ case State.elementEnd:
+ elementEnd_(action);
+ break;
+ case State.fieldNameEnd:
+ fieldNameEnd_(action);
+ break;
+ default:
+ throw new GeometryException("internal error");
+ }
+ }
+
+ private void accept_(int action) {
+ if (action != Action.accept) {
+ throw new GeometryException("invalid call");
+ }
+ }
+
+ private void start_(int action) {
+ if ((action & Action.addContainer) != 0) {
+ m_functionStack.removeLast();
+ } else {
+ throw new GeometryException("invalid call");
+ }
+ }
+
+ private void objectStart_(int action) {
+ if (action != Action.popObject && action != Action.addPair && action != Action.addKey)
+ throw new GeometryException("invalid call");
+
+ m_functionStack.removeLast();
+
+ if (action == Action.addPair) {
+ m_functionStack.add(State.pairEnd);
+ } else if (action == Action.addKey) {
+ m_functionStack.add(State.pairEnd);
+ m_functionStack.add(State.fieldNameEnd);
+ }
+ }
+
+ private void pairEnd_(int action) {
+ if (action == Action.addPair) {
+ m_jsonString.append(',');
+ } else if (action == Action.addKey) {
+ m_jsonString.append(',');
+ m_functionStack.add(State.fieldNameEnd);
+ } else if (action == Action.popObject) {
+ m_functionStack.removeLast();
+ } else {
+ throw new GeometryException("invalid call");
+ }
+ }
+
+ private void arrayStart_(int action) {
+ if ((action & Action.addValue) == 0 && action != Action.popArray)
+ throw new GeometryException("invalid call");
+
+ m_functionStack.removeLast();
+
+ if ((action & Action.addValue) != 0) {
+ m_functionStack.add(State.elementEnd);
+ }
+ }
+
+ private void elementEnd_(int action) {
+ if ((action & Action.addValue) != 0) {
+ m_jsonString.append(',');
+ } else if (action == Action.popArray) {
+ m_functionStack.removeLast();
+ } else {
+ throw new GeometryException("invalid call");
+ }
+ }
+
+ private void fieldNameEnd_(int action) {
+ if ((action & Action.addValue) == 0)
+ throw new GeometryException("invalid call");
+
+ m_functionStack.removeLast();
+ m_jsonString.append(':');
+ }
+
+ private void appendQuote_(String string) {
+ int count = 0;
+ int start = 0;
+ int end = string.length();
+
+ m_jsonString.append('"');
+
+ for (int i = 0; i < end; i++) {
+ switch (string.charAt(i)) {
+ case '"':
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\\"");
+ start = i + 1;
+ break;
+ case '\\':
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\\\");
+ start = i + 1;
+ break;
+ case '/':
+ if (i > 0 && string.charAt(i - 1) == '<') {
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\/");
+ start = i + 1;
+ } else {
+ count++;
+ }
+ break;
+ case '\b':
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\b");
+ start = i + 1;
+ break;
+ case '\f':
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\f");
+ start = i + 1;
+ break;
+ case '\n':
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\n");
+ start = i + 1;
+ break;
+ case '\r':
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\r");
+ start = i + 1;
+ break;
+ case '\t':
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ count = 0;
+ }
+ m_jsonString.append("\\t");
+ start = i + 1;
+ break;
+ default:
+ count++;
+ break;
+ }
+ }
+
+ if (count > 0) {
+ m_jsonString.append(string, start, start + count);
+ }
+
+ m_jsonString.append('"');
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/JsonWriter.java b/src/main/java/com/esri/core/geometry/JsonWriter.java
new file mode 100644
index 00000000..095f50e1
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/JsonWriter.java
@@ -0,0 +1,96 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+abstract class JsonWriter {
+
+ abstract Object getJson();
+
+ abstract void startObject();
+
+ abstract void startArray();
+
+ abstract void endObject();
+
+ abstract void endArray();
+
+ abstract void addFieldName(String fieldName);
+
+ abstract void addPairObject(String fieldName);
+
+ abstract void addPairArray(String fieldName);
+
+ abstract void addPairString(String fieldName, String v);
+
+ abstract void addPairDouble(String fieldName, double v);
+
+ abstract void addPairDouble(String fieldName, double v, int precision, boolean bFixedPoint);
+
+ abstract void addPairInt(String fieldName, int v);
+
+ abstract void addPairBoolean(String fieldName, boolean v);
+
+ abstract void addPairNull(String fieldName);
+
+ abstract void addValueObject();
+
+ abstract void addValueArray();
+
+ abstract void addValueString(String v);
+
+ abstract void addValueDouble(double v);
+
+ abstract void addValueDouble(double v, int precision, boolean bFixedPoint);
+
+ abstract void addValueInt(int v);
+
+ abstract void addValueBoolean(boolean v);
+
+ abstract void addValueNull();
+
+ protected interface Action {
+
+ static final int accept = 0;
+ static final int addObject = 1;
+ static final int addArray = 2;
+ static final int popObject = 4;
+ static final int popArray = 8;
+ static final int addKey = 16;
+ static final int addTerminal = 32;
+ static final int addPair = 64;
+ static final int addContainer = addObject | addArray;
+ static final int addValue = addContainer | addTerminal;
+ }
+
+ protected interface State {
+
+ static final int accept = 0;
+ static final int start = 1;
+ static final int objectStart = 2;
+ static final int arrayStart = 3;
+ static final int pairEnd = 4;
+ static final int elementEnd = 5;
+ static final int fieldNameEnd = 6;
+ }
+}
diff --git a/src/com/esri/core/geometry/Line.java b/src/main/java/com/esri/core/geometry/Line.java
similarity index 93%
rename from src/com/esri/core/geometry/Line.java
rename to src/main/java/com/esri/core/geometry/Line.java
index 6063caf5..ce7b7b23 100644
--- a/src/com/esri/core/geometry/Line.java
+++ b/src/main/java/com/esri/core/geometry/Line.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,26 +26,28 @@
package com.esri.core.geometry;
import com.esri.core.geometry.VertexDescription.Semantics;
+
import java.io.Serializable;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_LINE;
+
/**
* A straight line between a pair of points.
*
*/
public final class Line extends Segment implements Serializable {
- // UPDATED PORT TO MATCH NATIVE AS OF JAN 30 2011
-
- private static final long serialVersionUID = 2L;// TODO:remove as we use
- // writeReplace and
- // GeometrySerializer
-
- // HEADER DEF
@Override
public Geometry.Type getType() {
return Type.Line;
}
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_LINE + estimateMemorySize(m_attributes);
+ }
+
@Override
public double calculateLength2D() {
double dx = m_xStart - m_xEnd;
@@ -80,13 +82,6 @@ boolean _isDegenerate(double tolerance) {
return calculateLength2D() <= tolerance;
}
- @Override
- double _calculateSubLength(double t) {
- Point2D pt = getCoord2D(t);
- pt.sub(getStartXY());
- return pt.length();
- }
-
// HEADER DEF
// Cpp
@@ -101,7 +96,7 @@ public Line() {
m_description = vd;
}
- Line(double x1, double y1, double x2, double y2) {
+ public Line(double x1, double y1, double x2, double y2) {
m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
setStartXY(x1, y1);
setEndXY(x2, y2);
@@ -185,57 +180,40 @@ public Geometry createInstance() {
* ((m_yEnd - yorg) + (m_yStart - yorg)) * 0.5;
}
+ @Override
+ double tToLength(double t) {
+ return t * calculateLength2D();
+ }
+
+ @Override
+ double lengthToT(double len) {
+ return len / calculateLength2D();
+ }
+
double getCoordX_(double t) {
- // double x = m_x_end * t + (1.0 - t) * m_x_start; < 1.0 || (x >= m_xStart && x <= m_xEnd) || (x <= m_xStart && x >= m_xEnd));
- return x;
+ return MathUtils.lerp(m_xStart, m_xEnd, t);
}
double getCoordY_(double t) {
// Must match query_coord_2D and vice verse
// Also match get_attribute_as_dbl
- double y;
- if (t <= 0.5) {
- y = m_yStart + (m_yEnd - m_yStart) * t;
- } else {
- y = m_yEnd - (m_yEnd - m_yStart) * (1.0 - t);
- }
- assert (t < 0 || t > 1.0 || (y >= m_yStart && y <= m_yEnd) || (y <= m_yStart && y >= m_yEnd));
- return y;
+ return MathUtils.lerp(m_yStart, m_yEnd, t);
}
@Override
- void getCoord2D(double t, Point2D pt) {
+ public void getCoord2D(double t, Point2D pt) {
// We want:
// 1. When t == 0, get exactly Start
// 2. When t == 1, get exactly End
// 3. When m_x_end == m_x_start, we want m_x_start exactly
// 4. When m_y_end == m_y_start, we want m_y_start exactly
- if (t <= 0.5) {
- pt.x = m_xStart + (m_xEnd - m_xStart) * t;
- pt.y = m_yStart + (m_yEnd - m_yStart) * t;
- } else {
- pt.x = m_xEnd - (m_xEnd - m_xStart) * (1.0 - t);
- pt.y = m_yEnd - (m_yEnd - m_yStart) * (1.0 - t);
- }
- // assert(t < 0 || t > 1.0 || (pt.x >= m_x_start && pt.x <= m_x_end) ||
- // (pt.x <= m_x_start && pt.x >= m_x_end));
- // assert(t < 0 || t > 1.0 || (pt.y >= m_y_start && pt.y <= m_y_end) ||
- // (pt.y <= m_y_start && pt.y >= m_y_end));
+ MathUtils.lerp(m_xStart, m_yStart, m_xEnd, m_yEnd, t, pt);
}
@Override
- Segment cut(double t1, double t2) {
+ public Segment cut(double t1, double t2) {
SegmentBuffer segmentBuffer = new SegmentBuffer();
cut(t1, t2, segmentBuffer);
return segmentBuffer.get();
@@ -285,18 +263,18 @@ public double getAttributeAsDbl(double t, int semantics, int ordinate) {
case VertexDescription.Interpolation.LINEAR: {
double s = getStartAttributeAsDbl(semantics, ordinate);
double e = getEndAttributeAsDbl(semantics, ordinate);
- return s * (1.0 - t) + e * t;
+ return MathUtils.lerp(s, e, t);
}
case VertexDescription.Interpolation.ANGULAR: {
throw new GeometryException("not implemented");
}
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
@Override
- double getClosestCoordinate(Point2D inputPt, boolean bExtrapolate) {
+ public double getClosestCoordinate(Point2D inputPt, boolean bExtrapolate) {
double vx = m_xEnd - m_xStart;
double vy = m_yEnd - m_yStart;
double v2 = vx * vx + vy * vy;
@@ -416,7 +394,7 @@ boolean _isIntersectingPoint(Point2D pt, double tolerance,
* given tolerance.
*/
@Override
- boolean isIntersecting(Point2D pt, double tolerance) {
+ public boolean isIntersecting(Point2D pt, double tolerance) {
return _isIntersectingPoint(pt, tolerance, false);
}
@@ -556,13 +534,30 @@ int _side(double ptX, double ptY) {
return NumberUtils.TheNaN;
}
+ @Override
+ public boolean equals(Object other) {
+ if (other == null)
+ return false;
+
+ if (other == this)
+ return true;
+
+ if (other.getClass() != getClass())
+ return false;
+
+ return _equalsImpl((Segment)other);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
boolean equals(Line other) {
if (other == this)
return true;
- // FIXME review use of Java's instance of to see if it complies with
- // Borgs
- if (other instanceof Line)// (!IS_INSTANCE_OF(other, Line))
+ if (!(other instanceof Line))
return false;
return _equalsImpl((Segment) other);
@@ -986,17 +981,44 @@ static int _intersectLineLine(Line line1, Line line2,
return 1;
}
+
+ @Override
+ public void replaceNaNs(int semantics, double value) {
+ addAttribute(semantics);
+ if (isEmpty())
+ return;
+
+ int ncomps = VertexDescription.getComponentCount(semantics);
+ for (int i = 0; i < ncomps; i++) {
+ double v = _getAttributeAsDbl(0, semantics, i);
+ if (Double.isNaN(v))
+ _setAttribute(0, semantics, 0, value);
+
+ v = _getAttributeAsDbl(1, semantics, i);
+ if (Double.isNaN(v))
+ _setAttribute(1, semantics, 0, value);
+ }
+ }
+
@Override
int getYMonotonicParts(SegmentBuffer[] monotonicSegments) {
return 0;
}
- // FIXME In Native borg this has no implementation
@Override
void _copyToImpl(Segment dst) {
// TODO Auto-generated method stub
}
+ /**
+ * The output of this method can be only used for debugging. It is subject to change without notice.
+ */
+ @Override
+ public String toString() {
+ String s = "Line: [" + m_xStart + ", " + m_yStart + ", " + m_xEnd + ", " + m_yEnd +"]";
+ return s;
+ }
+
}
diff --git a/src/com/esri/core/geometry/ListeningGeometryCursor.java b/src/main/java/com/esri/core/geometry/ListeningGeometryCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/ListeningGeometryCursor.java
rename to src/main/java/com/esri/core/geometry/ListeningGeometryCursor.java
index 04de301e..965a6798 100644
--- a/src/com/esri/core/geometry/ListeningGeometryCursor.java
+++ b/src/main/java/com/esri/core/geometry/ListeningGeometryCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/LnSrlzr.java b/src/main/java/com/esri/core/geometry/LnSrlzr.java
new file mode 100644
index 00000000..b1bd001f
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/LnSrlzr.java
@@ -0,0 +1,93 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+//This is a writeReplace class for Lin
+public class LnSrlzr implements Serializable {
+ private static final long serialVersionUID = 1L;
+ double[] attribs;
+ int descriptionBitMask;
+
+ public Object readResolve() throws ObjectStreamException {
+ Line ln = null;
+ if (descriptionBitMask == -1)
+ return null;
+
+ try {
+ VertexDescription vd = VertexDescriptionDesignerImpl
+ .getVertexDescription(descriptionBitMask);
+ ln = new Line(vd);
+ if (attribs != null) {
+ ln.setStartXY(attribs[0], attribs[1]);
+ ln.setEndXY(attribs[2], attribs[3]);
+ int index = 4;
+ for (int i = 1, n = vd.getAttributeCount(); i < n; i++) {
+ int semantics = vd.getSemantics(i);
+ int comps = VertexDescription.getComponentCount(semantics);
+ for (int ord = 0; ord < comps; ord++) {
+ ln.setStartAttribute(semantics, ord, attribs[index++]);
+ ln.setEndAttribute(semantics, ord, attribs[index++]);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot read geometry from stream");
+ }
+
+ return ln;
+ }
+
+ public void setGeometryByValue(Line ln) throws ObjectStreamException {
+ try {
+ attribs = null;
+ if (ln == null) {
+ descriptionBitMask = -1;
+ }
+
+ VertexDescription vd = ln.getDescription();
+ descriptionBitMask = vd.m_semanticsBitArray;
+
+ attribs = new double[vd.getTotalComponentCount() * 2];
+ attribs[0] = ln.getStartX();
+ attribs[1] = ln.getStartY();
+ attribs[2] = ln.getEndX();
+ attribs[3] = ln.getEndY();
+ int index = 4;
+ for (int i = 1, n = vd.getAttributeCount(); i < n; i++) {
+ int semantics = vd.getSemantics(i);
+ int comps = VertexDescription.getComponentCount(semantics);
+ for (int ord = 0; ord < comps; ord++) {
+ attribs[index++] = ln.getStartAttributeAsDbl(semantics, ord);
+ attribs[index++] = ln.getEndAttributeAsDbl(semantics, ord);
+ }
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot serialize this geometry");
+ }
+ }
+}
diff --git a/src/com/esri/core/geometry/MapGeometry.java b/src/main/java/com/esri/core/geometry/MapGeometry.java
similarity index 54%
rename from src/com/esri/core/geometry/MapGeometry.java
rename to src/main/java/com/esri/core/geometry/MapGeometry.java
index 32150cbd..dbd90646 100644
--- a/src/com/esri/core/geometry/MapGeometry.java
+++ b/src/main/java/com/esri/core/geometry/MapGeometry.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@
package com.esri.core.geometry;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_MAPGEOMETRY;
+
import java.io.Serializable;
/**
@@ -32,7 +34,7 @@
* together. To work with a geometry object in a map it is necessary to have a
* spatial reference defined for this geometry.
*/
-public final class MapGeometry implements Serializable {
+public class MapGeometry implements Serializable {
private static final long serialVersionUID = 1L;
Geometry m_geometry = null;
@@ -87,4 +89,77 @@ public void setSpatialReference(SpatialReference sr) {
public SpatialReference getSpatialReference() {
return sr;
}
+
+ /**
+ * The output of this method can be only used for debugging. It is subject to change without notice.
+ */
+ @Override
+ public String toString() {
+ String snippet = OperatorExportToJson.local().execute(getSpatialReference(), getGeometry());
+ if (snippet.length() > 200) {
+ return snippet.substring(0, 197) + "... ("+snippet.length()+" characters)";
+ }
+ else {
+ return snippet;
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null)
+ return false;
+
+ if (other == this)
+ return true;
+
+ if (other.getClass() != getClass())
+ return false;
+
+ MapGeometry omg = (MapGeometry)other;
+ SpatialReference sr = getSpatialReference();
+ Geometry g = getGeometry();
+ SpatialReference osr = omg.getSpatialReference();
+ Geometry og = omg.getGeometry();
+
+ if (sr != osr) {
+ if (sr == null || !sr.equals(osr))
+ return false;
+ }
+
+ if (g != og) {
+ if (g == null || !g.equals(og))
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns an estimate of this object size in bytes.
+ *
+ * This estimate doesn't include the size of the {@link SpatialReference} object
+ * because instances of {@link SpatialReference} are expected to be shared among
+ * geometry objects.
+ *
+ * @return Returns an estimate of this object size in bytes.
+ */
+ public long estimateMemorySize() {
+ long sz = SIZE_OF_MAPGEOMETRY;
+ if (m_geometry != null)
+ sz += m_geometry.estimateMemorySize();
+ return sz;
+ }
+
+ @Override
+ public int hashCode() {
+ SpatialReference sr = getSpatialReference();
+ Geometry g = getGeometry();
+ int hc = 0x2937912;
+ if (sr != null)
+ hc ^= sr.hashCode();
+ if (g != null)
+ hc ^= g.hashCode();
+
+ return hc;
+ }
}
diff --git a/src/com/esri/core/geometry/MapGeometryCursor.java b/src/main/java/com/esri/core/geometry/MapGeometryCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/MapGeometryCursor.java
rename to src/main/java/com/esri/core/geometry/MapGeometryCursor.java
index 81b0b195..b7cec8e4 100644
--- a/src/com/esri/core/geometry/MapGeometryCursor.java
+++ b/src/main/java/com/esri/core/geometry/MapGeometryCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/MapOGCStructure.java b/src/main/java/com/esri/core/geometry/MapOGCStructure.java
similarity index 97%
rename from src/com/esri/core/geometry/MapOGCStructure.java
rename to src/main/java/com/esri/core/geometry/MapOGCStructure.java
index 61ec600e..c4eb5241 100644
--- a/src/com/esri/core/geometry/MapOGCStructure.java
+++ b/src/main/java/com/esri/core/geometry/MapOGCStructure.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/MathUtils.java b/src/main/java/com/esri/core/geometry/MathUtils.java
new file mode 100644
index 00000000..92d5d8dd
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/MathUtils.java
@@ -0,0 +1,238 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+final class MathUtils {
+ /**
+ * The implementation of the Kahan summation algorithm. Use to get better
+ * precision when adding a lot of values.
+ */
+ static final class KahanSummator {
+ private double sum; // the accumulated sum
+ private double compensation;
+ private double startValue; // the Base (the class returns sum +
+ // startValue)
+
+ /**
+ * initialize to the given start value. \param startValue_ The value to
+ * be added to the accumulated sum.
+ */
+ KahanSummator(double startValue_) {
+ startValue = startValue_;
+ reset();
+ }
+
+ /**
+ * Resets the accumulated sum to zero. The getResult() returns
+ * startValue_ after this call.
+ */
+ void reset() {
+ sum = 0;
+ compensation = 0;
+ }
+
+ /**
+ * add a value.
+ */
+ void add(double v) {
+ double y = v - compensation;
+ double t = sum + y;
+ double h = t - sum;
+ compensation = h - y;
+ sum = t;
+ }
+
+ /**
+ * Subtracts a value.
+ */
+ void sub(double v) {
+ add(-v);
+ }
+
+ /**
+ * add another summator.
+ */
+ void add(/* const */KahanSummator v) {
+ double y = (v.getResult() + v.compensation) - compensation;
+ double t = sum + y;
+ double h = t - sum;
+ compensation = h - y;
+ sum = t;
+ }
+
+ /**
+ * Subtracts another summator.
+ */
+ void sub(/* const */KahanSummator v) {
+ double y = -(v.getResult() - v.compensation) - compensation;
+ double t = sum + y;
+ double h = t - sum;
+ compensation = h - y;
+ sum = t;
+ }
+
+ /**
+ * Returns current value of the sum.
+ */
+ double getResult() /* const */{
+ return startValue + sum;
+ }
+
+ KahanSummator plusEquals(double v) {
+ add(v);
+ return this;
+ }
+
+ KahanSummator minusEquals(double v) {
+ add(-v);
+ return this;
+ }
+
+ KahanSummator plusEquals(/* const */KahanSummator v) {
+ add(v);
+ return this;
+ }
+
+ KahanSummator minusEquals(/* const */KahanSummator v) {
+ sub(v);
+ return this;
+ }
+ }
+
+ /**
+ * Returns one value with the sign of another (like copysign).
+ */
+ static double copySign(double x, double y) {
+ return y >= 0.0 ? Math.abs(x) : -Math.abs(x);
+ }
+
+ /**
+ * Calculates sign of the given value. Returns 0 if the value is equal to 0.
+ */
+ static int sign(double value) {
+ return value < 0 ? -1 : (value > 0) ? 1 : 0;
+ }
+
+ /**
+ * Rounds towards zero.
+ */
+ static double truncate(double v) {
+ if (v >= 0)
+ return Math.floor(v);
+ else
+ return -Math.floor(-v);
+ }
+
+ /**
+ * C fmod function.
+ */
+ static double FMod(double x, double y) {
+ return x - truncate(x / y) * y;
+ }
+
+
+
+
+ /**
+ * Rounds double to the closest integer value.
+ */
+ static double round(double v) {
+ return Math.floor(v + 0.5);
+ }
+ static double sqr(double v) {
+ return v * v;
+ }
+
+ /**
+ *Computes interpolation between two values, using the interpolation factor t.
+ *The interpolation formula is (end - start) * t + start.
+ *However, the computation ensures that t = 0 produces exactly start, and t = 1, produces exactly end.
+ *It also guarantees that for 0 <= t <= 1, the interpolated value v is between start and end.
+ */
+ static double lerp(double start_, double end_, double t) {
+ // When end == start, we want result to be equal to start, for all t
+ // values. At the same time, when end != start, we want the result to be
+ // equal to start for t==0 and end for t == 1.0
+ // The regular formula end_ * t + (1.0 - t) * start_, when end_ ==
+ // start_, and t at 1/3, produces value different from start
+ double v;
+ if (t <= 0.5)
+ v = start_ + (end_ - start_) * t;
+ else
+ v = end_ - (end_ - start_) * (1.0 - t);
+
+ assert (t < 0 || t > 1.0 || (v >= start_ && v <= end_) || (v <= start_ && v >= end_) || NumberUtils.isNaN(start_) || NumberUtils.isNaN(end_));
+ return v;
+ }
+
+ /**
+ *Computes interpolation between two values, using the interpolation factor t.
+ *The interpolation formula is (end - start) * t + start.
+ *However, the computation ensures that t = 0 produces exactly start, and t = 1, produces exactly end.
+ *It also guarantees that for 0 <= t <= 1, the interpolated value v is between start and end.
+ */
+ static void lerp(Point2D start_, Point2D end_, double t, Point2D result) {
+ assert(start_ != result);
+ // When end == start, we want result to be equal to start, for all t
+ // values. At the same time, when end != start, we want the result to be
+ // equal to start for t==0 and end for t == 1.0
+ // The regular formula end_ * t + (1.0 - t) * start_, when end_ ==
+ // start_, and t at 1/3, produces value different from start
+ double rx, ry;
+ if (t <= 0.5) {
+ rx = start_.x + (end_.x - start_.x) * t;
+ ry = start_.y + (end_.y - start_.y) * t;
+ }
+ else {
+ rx = end_.x - (end_.x - start_.x) * (1.0 - t);
+ ry = end_.y - (end_.y - start_.y) * (1.0 - t);
+ }
+
+ assert (t < 0 || t > 1.0 || (rx >= start_.x && rx <= end_.x) || (rx <= start_.x && rx >= end_.x));
+ assert (t < 0 || t > 1.0 || (ry >= start_.y && ry <= end_.y) || (ry <= start_.y && ry >= end_.y));
+ result.x = rx;
+ result.y = ry;
+ }
+
+ static void lerp(double start_x, double start_y, double end_x, double end_y, double t, Point2D result) {
+ // When end == start, we want result to be equal to start, for all t
+ // values. At the same time, when end != start, we want the result to be
+ // equal to start for t==0 and end for t == 1.0
+ // The regular formula end_ * t + (1.0 - t) * start_, when end_ ==
+ // start_, and t at 1/3, produces value different from start
+ if (t <= 0.5) {
+ result.x = start_x + (end_x - start_x) * t;
+ result.y = start_y + (end_y - start_y) * t;
+ }
+ else {
+ result.x = end_x - (end_x - start_x) * (1.0 - t);
+ result.y = end_y - (end_y - start_y) * (1.0 - t);
+ }
+
+ assert (t < 0 || t > 1.0 || (result.x >= start_x && result.x <= end_x) || (result.x <= start_x && result.x >= end_x));
+ assert (t < 0 || t > 1.0 || (result.y >= start_y && result.y <= end_y) || (result.y <= start_y && result.y >= end_y));
+ }
+
+}
diff --git a/src/com/esri/core/geometry/MultiPath.java b/src/main/java/com/esri/core/geometry/MultiPath.java
similarity index 87%
rename from src/com/esri/core/geometry/MultiPath.java
rename to src/main/java/com/esri/core/geometry/MultiPath.java
index d0749652..48cf8bd9 100644
--- a/src/com/esri/core/geometry/MultiPath.java
+++ b/src/main/java/com/esri/core/geometry/MultiPath.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -39,12 +39,12 @@ public VertexDescription getDescription() {
}
@Override
- void assignVertexDescription(VertexDescription src) {
+ public void assignVertexDescription(VertexDescription src) {
m_impl.assignVertexDescription(src);
}
@Override
- void mergeVertexDescription(VertexDescription src) {
+ public void mergeVertexDescription(VertexDescription src) {
m_impl.mergeVertexDescription(src);
}
@@ -124,12 +124,12 @@ public Point2D getXY(int index) {
}
@Override
- void getXY(int index, Point2D pt) {
+ public void getXY(int index, Point2D pt) {
m_impl.getXY(index, pt);
}
@Override
- void setXY(int index, Point2D pt) {
+ public void setXY(int index, Point2D pt) {
m_impl.setXY(index, pt);
}
@@ -152,6 +152,10 @@ public void queryEnvelope(Envelope env) {
public void queryEnvelope2D(Envelope2D env) {
m_impl.queryEnvelope2D(env);
}
+
+ public void queryPathEnvelope2D(int pathIndex, Envelope2D env) {
+ m_impl.queryPathEnvelope2D(pathIndex, env);
+ }
@Override
void queryEnvelope3D(Envelope3D env) {
@@ -179,14 +183,19 @@ public void copyTo(Geometry dst) {
m_impl.copyTo((Geometry) dst._getImpl());
}
- Geometry getBoundary() {
+ @Override
+ public Geometry getBoundary() {
return m_impl.getBoundary();
}
@Override
- void queryCoordinates(Point2D[] dst) {
+ public void queryCoordinates(Point2D[] dst) {
m_impl.queryCoordinates(dst);
}
+
+ public void queryCoordinates(Point2D[] dst, int dstSize, int beginIndex, int endIndex) {
+ m_impl.queryCoordinates(dst, dstSize, beginIndex, endIndex);
+ }
@Override
void queryCoordinates(Point3D[] dst) {
@@ -194,7 +203,7 @@ void queryCoordinates(Point3D[] dst) {
}
@Override
- void queryCoordinates(Point[] dst) {
+ public void queryCoordinates(Point[] dst) {
m_impl.queryCoordinates(dst);
}
@@ -268,6 +277,41 @@ void addPath(Point2D[] points, int count, boolean bForward) {
m_impl.addPath(points, count, bForward);
}
+ /**
+ * Adds segments from a source multipath to this MultiPath.
+ *
+ * @param src
+ * The source MultiPath to add segments from.
+ * @param srcPathIndex
+ * The index of the path in the the source MultiPath.
+ * @param srcSegmentFrom
+ * The index of first segment in the path to start adding from.
+ * The value has to be between 0 and
+ * src.getSegmentCount(srcPathIndex) - 1.
+ * @param srcSegmentCount
+ * The number of segments to add. If 0, the function does
+ * nothing.
+ * @param bStartNewPath
+ * When true, a new path is added and segments are added to it.
+ * Otherwise the segments are added to the last path of this
+ * MultiPath.
+ *
+ * If bStartNewPath false, the first point of the first source
+ * segment is not added. This is done to ensure proper connection
+ * to existing segments. When the source path is closed, and the
+ * closing segment is among those to be added, it is added also
+ * as a closing segment, not as a real segment. Use add_segment
+ * instead if you do not like that behavior.
+ *
+ * This MultiPath obtains all missing attributes from the src
+ * MultiPath.
+ */
+ public void addSegmentsFromPath(MultiPath src, int srcPathIndex,
+ int srcSegmentFrom, int srcSegmentCount, boolean bStartNewPath) {
+ m_impl.addSegmentsFromPath((MultiPathImpl) src._getImpl(),
+ srcPathIndex, srcSegmentFrom, srcSegmentCount, bStartNewPath);
+ }
+
/**
* Adds a new segment to this multipath.
*
@@ -599,7 +643,7 @@ void closePathWithBezier(Point2D controlPoint1, Point2D controlPoint2) {
* Closes last path of the MultiPath with the Arc Segment.
*/
void closePathWithArc() {
- throw new RuntimeException("not implemented"); /* FIXME */
+ throw new RuntimeException("not implemented");
}
/**
@@ -636,31 +680,6 @@ boolean hasNonLinearSegments(int pathIndex) {
return m_impl.hasNonLinearSegments(pathIndex);
}
- // //Elliptic Arc
- // //returns true, if parameters of the arc are correct (conform with
- // equation of elliptic arc)
- // //returns false, if parameters are incorrect.
- // //In the latter case the command will be executed anyway, however, the
- // EllipseAxes will be automatically corrected
- // //to conform with equation of the elliptic arc.
- // //Elliptic arcs are stored as rational bezier curves. Use
- // CalcEllipticArcParams function
- // //to calculate geometric parameters of arc
- // //bCW - clockwise (true) or anti-clockwise (false).
- // //The type parameter helps to resolve situation, when start and end point
- // of arc are too close.
- // //It gives a hint to the function how to deal with the situation, when
- // start point equal or almost equal to the end point.
- // //If type == unknownArc and EndPoint == start point, the arc is a point.
- // //If type == minorArc, and abs(SweepAngle - 2 * PI) < 0.001 the arc is
- // replaced by the line from start point to EndPoint.
- // //If type == majorArc, and abs(SweepAngle) < 0.001 the SweepAngle is
- // replaced by SweepAngle + (bCW ? -1. : 1.) * 2. * PI.
- // //Here SweepAngle is calculated sweep angle of the arc.
- // boolean ArcTo(Point2D endPoint, Point2D ellipseAxes, Point2D center,
- // double axisXRotationRad, boolean bCW, enum enumArcType type =
- // unknownArc);
-
/**
* Adds a rectangular closed Path to the MultiPathImpl.
*
@@ -669,7 +688,7 @@ boolean hasNonLinearSegments(int pathIndex) {
* @param bReverse
* Creates reversed path.
*/
- void addEnvelope(Envelope2D envSrc, boolean bReverse) {
+ public void addEnvelope(Envelope2D envSrc, boolean bReverse) {
m_impl.addEnvelope(envSrc, bReverse);
}
@@ -685,22 +704,6 @@ public void addEnvelope(Envelope envSrc, boolean bReverse) {
m_impl.addEnvelope(envSrc, bReverse);
}
- // void AddRoundRect(Envelope2D envSrc, double EllipseWidth, double
- // EllipseHeight, boolean bReverse);
-
- // //Adds ellipse with center point Center and rotation angle between axis X
- // and ellipse axes Axes.X equal to RotationAngle.
- // boolean AddEllipse(Point2D center, Point2D axes, double rotationAngle,
- // boolean bReverse);
-
- // //adds a pie - a closed figure, consisting of two lines and a segment of
- // an ellipse
- // //pie is drawn always ccw (when axis X is left-right, axis Y is
- // bottom-up). negative sweep angle is converted to positive.
- // //angles greater than 2 * pi are converted back into the 2 * pi range.
- // boolean AddPie(const DRect & rect, double startAngle, double sweepAngle,
- // boolean bReverse);
-
/**
* Returns a SegmentIterator that is set right before the beginning of the
* multipath. Calling nextPath() will set the iterator to the first path of
@@ -756,12 +759,12 @@ public int hashCode() {
}
@Override
- void getPointByVal(int index, Point outPoint) {
+ public void getPointByVal(int index, Point outPoint) {
m_impl.getPointByVal(index, outPoint);
}
@Override
- void setPointByVal(int index, Point point) {
+ public void setPointByVal(int index, Point point) {
m_impl.setPointByVal(index, point);
}
@@ -770,4 +773,9 @@ public int getStateFlag() {
return m_impl.getStateFlag();
}
+ @Override
+ public void replaceNaNs(int semantics, double value) {
+ m_impl.replaceNaNs(semantics, value);
+ }
+
}
diff --git a/src/com/esri/core/geometry/MultiPathImpl.java b/src/main/java/com/esri/core/geometry/MultiPathImpl.java
similarity index 93%
rename from src/com/esri/core/geometry/MultiPathImpl.java
rename to src/main/java/com/esri/core/geometry/MultiPathImpl.java
index e8062f3a..d70e5c5d 100644
--- a/src/com/esri/core/geometry/MultiPathImpl.java
+++ b/src/main/java/com/esri/core/geometry/MultiPathImpl.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,8 +25,9 @@
package com.esri.core.geometry;
-final class MultiPathImpl extends MultiVertexGeometryImpl {
+import static com.esri.core.geometry.SizeOf.SIZE_OF_MULTI_PATH_IMPL;
+final class MultiPathImpl extends MultiVertexGeometryImpl {
protected boolean m_bPolygon;
protected Point m_moveToPoint;
protected double m_cachedLength2D;
@@ -52,11 +53,38 @@ final class MultiPathImpl extends MultiVertexGeometryImpl {
protected AttributeStreamOfDbl m_segmentParams;
protected int m_curveParamwritePoint;
private int m_currentPathIndex;
+ private int m_fill_rule = Polygon.FillRule.enumFillRuleOddEven;
static int[] _segmentParamSizes = { 0, 0, 6, 0, 8, 0 }; // None, Line,
// Bezier, XXX, Arc,
// XXX;
+ @Override
+ public long estimateMemorySize()
+ {
+ long size = SIZE_OF_MULTI_PATH_IMPL +
+ + (m_envelope != null ? m_envelope.estimateMemorySize() : 0)
+ + (m_moveToPoint != null ? m_moveToPoint.estimateMemorySize() : 0)
+ + (m_cachedRingAreas2D != null ? m_cachedRingAreas2D.estimateMemorySize() : 0)
+ + (m_paths != null ? m_paths.estimateMemorySize() : 0)
+ + (m_pathFlags != null ? m_pathFlags.estimateMemorySize() : 0)
+ + (m_segmentFlags != null ? m_segmentFlags.estimateMemorySize() : 0)
+ + (m_segmentParamIndex != null ? m_segmentParamIndex.estimateMemorySize() : 0)
+ + (m_segmentParams != null ? m_segmentParams.estimateMemorySize() : 0);
+
+ if (m_vertexAttributes != null) {
+ for (int i = 0; i < m_vertexAttributes.length; i++) {
+ size += m_vertexAttributes[i].estimateMemorySize();
+ }
+ }
+
+ if (m_accelerators != null) {
+ size += m_accelerators.estimateMemorySize();
+ }
+
+ return size;
+ }
+
public boolean hasNonLinearSegments() {
return m_curveParamwritePoint > 0;
}
@@ -131,10 +159,10 @@ public void startPath(Point3D point) {
// Reviewed vs. Native Jan 11, 2011
public void startPath(Point point) {
if (point.isEmpty())
- // FIXME exc
throw new IllegalArgumentException();// throw new
// IllegalArgumentException();
+ mergeVertexDescription(point.getDescription());
_initPathStartPoint();
point.copyTo(m_moveToPoint);
@@ -292,41 +320,36 @@ public void bezierTo(Point2D controlPoint1, Point2D controlPoint2,
public void openPath(int pathIndex) {
_touch();
if (m_bPolygon)
- // FIXME exc
- throw new GeometryException("internal error");// do not call this
+ throw GeometryException.GeometryInternalError();// do not call this
// method on a
// polygon
int pathCount = getPathCount();
if (pathIndex > getPathCount())
- // FIXME exc
throw new IllegalArgumentException();
if (m_pathFlags == null)
- // FIXME exc
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
m_pathFlags.clearBits(pathIndex, (byte) PathFlags.enumClosed);
}
- // Reviewed vs. Native Jan 11, 2011
- // Major Changes on 16th of January
public void openPathAndDuplicateStartVertex(int pathIndex) {
_touch();
if (m_bPolygon)
- throw new GeometryException("internal error");// do not call this
+ throw GeometryException.GeometryInternalError();// do not call this
// method on a
// polygon
int pathCount = getPathCount();
if (pathIndex > pathCount)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
if (!isClosedPath(pathIndex))
return;// do not open if open
if (m_pathFlags == null)// if (!m_pathFlags)
- throw new GeometryException("nternal_error");
+ throw GeometryException.GeometryInternalError();
int oldPointCount = m_pointCount;
int pathIndexStart = getPathStart(pathIndex);
@@ -359,13 +382,12 @@ public void openPathAndDuplicateStartVertex(int pathIndex) {
public void openAllPathsAndDuplicateStartVertex() {
_touch();
if (m_bPolygon)
- // FIXME
- throw new GeometryException("internal error");// do not call this
+ throw GeometryException.GeometryInternalError();// do not call this
// method on a
// polygon
if (m_pathFlags == null)// if (!m_pathFlags)
- throw new GeometryException("nternal_error");
+ throw GeometryException.GeometryInternalError();
_verifyAllStreams();
@@ -579,16 +601,14 @@ public void addSegment(Segment segment, boolean bStartNewPath) {
if (segment.getType() == Type.Line) {
Point point = new Point();
if (bStartNewPath || isEmpty()) {
- // FIXME change getStart to queryStart!!!!!!!
segment.queryStart(point);
startPath(point);
}
- // FIXME change getStart to queryEnd
+
segment.queryEnd(point);
lineTo(point);
} else {
- // FIXME
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
@@ -665,9 +685,6 @@ public void add(MultiPathImpl src, boolean bReversePaths) {
addPath(src, i, !bReversePaths);
}
- // Reviewed vs. Native Jan 11, 2011
- // FIXME THERE IS POTENTIALLY A BUG WITH the use of AttributeStream
- // InsertRange
public void addPath(MultiPathImpl src, int srcPathIndex, boolean bForward) {
insertPath(-1, src, srcPathIndex, bForward);
}
@@ -677,56 +694,6 @@ public void addPath(Point2D[] _points, int count, boolean bForward) {
insertPath(-1, _points, 0, count, bForward);
}
- // FIXME add add to attributestream base
- // public void addPath(double[][] _points, int count, boolean bForward)
- // {
- // m_bPathStarted = false;
- //
- // int oldPointCount = m_pointCount;
- // _verifyAllStreams();
- //
- // int newPointCount = oldPointCount + count;
- // if (oldPointCount > 0)
- // m_paths.add(newPointCount);
- // else
- // {
- // // _ASSERT(m_paths.size() == 2);
- // m_paths.write(1, newPointCount);
- // }
- //
- // _resizeImpl(newPointCount);
- //
- // _verifyAllStreams();
- //
- // if (m_segmentParamIndex != null)
- // {
- // m_segmentParamIndex.resize(m_pointCount, -1);
- // m_segmentFlags.resize(m_pointCount, (byte)SegmentFlags.enumLineSeg);
- // }
- //
- // if (oldPointCount > 0)
- // m_pathFlags.add(0);
- //
- // // _ASSERT(m_pathFlags.size() == m_paths.size());
- //
- // if (m_bPolygon)
- // {
- // //Marc the path as closed
- // m_pathFlags.write(m_pathFlags.size() - 2, (byte)PathFlags.enumClosed);
- // }
- //
- // int j = oldPointCount;
- // AttributeStreamOfDbl points =
- // (AttributeStreamOfDbl)m_vertexAttributes[0];
- // for (int i = 0; i < count; i++, j++)
- // {
- // int index = (bForward ? i : count - i - 1);
- // points.write(2 * j, _points[index][0]);
- // points.write(2 * j + 1, _points[index][1]);
- // }
- // }
- //
-
public void addSegmentsFromPath(MultiPathImpl src, int src_path_index,
int src_segment_from, int src_segment_count,
boolean b_start_new_path) {
@@ -824,7 +791,7 @@ public void addSegmentsFromPath(MultiPathImpl src, int src_path_index,
if (hasNonLinearSegments()) {
// TODO: implement me. For example as a while loop over all curves.
// Replace, calling ReplaceSegment
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// m_segment_flags->write_range((get_path_start(path_index) +
// before_point_index + src_point_count), (oldPointCount -
// get_path_start(path_index) - before_point_index),
@@ -848,7 +815,7 @@ public void addSegmentsFromPath(MultiPathImpl src, int src_path_index,
if (src.hasNonLinearSegments(src_path_index)) {
// TODO: implement me. For example as a while loop over all curves.
// Replace, calling ReplaceSegment
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
notifyModified(DirtyFlags.DirtyCoordinates);
@@ -866,7 +833,6 @@ public void reversePath(int pathIndex) {
_verifyAllStreams();
int pathCount = getPathCount();
if (pathIndex >= pathCount)
- // FIXME exc
throw new IllegalArgumentException();
int reversedPathStart = getPathStart(pathIndex);
@@ -1119,8 +1085,8 @@ public void insertPoints(int pathIndex, int beforePointIndex,
if (srcPathIndex < 0)
srcPathIndex = src.getPathCount() - 1;
- if (pathIndex > getPathCount()
- || beforePointIndex > getPathSize(pathIndex)
+ if (pathIndex > getPathCount() || beforePointIndex >= 0
+ && beforePointIndex > getPathSize(pathIndex)
|| srcPathIndex >= src.getPathCount()
|| srcPointCount > src.getPathSize(srcPathIndex))
throw new GeometryException("index out of bounds");
@@ -1209,7 +1175,7 @@ public void insertPoints(int pathIndex, int beforePointIndex,
if (src.hasNonLinearSegments(srcPathIndex)) {
// TODO: implement me. For example as a while loop over all curves.
// Replace, calling ReplaceSegment
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
for (int ipath = pathIndex + 1, npaths = getPathCount(); ipath <= npaths; ipath++) {
@@ -1522,7 +1488,8 @@ public double calculatePathLength2D(int pathIndex) /* const */
return sub_length;
}
- Geometry getBoundary() {
+ @Override
+ public Geometry getBoundary() {
return Boundary.calculate(this, null);
}
@@ -1692,8 +1659,7 @@ void interpolateAttributes_(int semantics, int from_path_index,
double segment_length = segment.calculateLength2D();
cumulative_length += segment_length;
double t = cumulative_length / sub_length;
- interpolated_attribute = (1.0 - t) * from_attribute + t
- * to_attribute;
+ interpolated_attribute = MathUtils.lerp(from_attribute, to_attribute, t);
if (!seg_iter.isClosingSegment())
setAttribute(semantics, seg_iter.getEndPointIndex(),
@@ -1736,8 +1702,7 @@ void interpolateAttributes_(int semantics, int path_index,
double segment_length = segment.calculateLength2D();
cumulative_length += segment_length;
double t = cumulative_length / sub_length;
- prev_interpolated_attribute = (1.0 - t) * from_attribute + t
- * to_attribute;
+ prev_interpolated_attribute = MathUtils.lerp(from_attribute, to_attribute, t);
} while (seg_iter.getEndPointIndex() != absolute_to_index);
}
@@ -1797,29 +1762,24 @@ public void applyTransformation(Transformation2D transform, int pathIndex) {
case SegmentFlags.enumBezierSeg: {
ptControl.x = m_segmentParams.read(segIndex);
ptControl.y = m_segmentParams.read(segIndex + 1);
- // FIXME rohit has transform returning the object rather
- // than transforming the input
transform.transform(ptControl, ptControl);
m_segmentParams.write(segIndex, ptControl.x);
m_segmentParams.write(segIndex + 1, ptControl.y);
ptControl.x = m_segmentParams.read(segIndex + 3);
ptControl.y = m_segmentParams.read(segIndex + 4);
- // FIXME rohit has transform returning the object rather
- // than transforming the input
transform.transform(ptControl, ptControl);
m_segmentParams.write(segIndex + 3, ptControl.x);
m_segmentParams.write(segIndex + 4, ptControl.y);
}
break;
case SegmentFlags.enumArcSeg:
- throw new GeometryException("internal error");// FIXME
+ throw GeometryException.GeometryInternalError();
}
}
}
- // FIXME rohit has transform returning the object rather than
- // transforming the input
+
transform.transform(ptStart, ptStart);
points.write(ipoint * 2, ptStart.x);
points.write(ipoint * 2 + 1, ptStart.y);
@@ -1872,11 +1832,12 @@ public void applyTransformation(Transformation3D transform) {
}
break;
case SegmentFlags.enumArcSeg:
- throw new GeometryException("internal error");// FIXME
+ throw GeometryException.GeometryInternalError();
}
}
}
+
ptStart = transform.transform(ptStart);
points.write(ipoint * 2, ptStart.x);
points.write(ipoint * 2 + 1, ptStart.y);
@@ -1910,8 +1871,8 @@ void _copyToImpl(MultiVertexGeometryImpl dst) {
MultiPathImpl dstPoly = (MultiPathImpl) dst;
dstPoly.m_bPathStarted = false;
dstPoly.m_curveParamwritePoint = m_curveParamwritePoint;
-
- // FIXME there is no cloning in here. Is this necessary?
+ dstPoly.m_fill_rule = m_fill_rule;
+
if (m_paths != null)
dstPoly.m_paths = new AttributeStreamOfInt32(m_paths);
else
@@ -1968,25 +1929,6 @@ public double calculateLength2D() {
return len.getResult();
}
- // FIXME figure out hascode
- // int getHashCode()
- // {
- // int hashCode = MultiVertexGeometryImpl.getHashCode();
- //
- // if (!isEmptyImpl())
- // {
- // int pathCount = getPathCount();
- //
- // if (m_paths != null)
- // m_paths.calculateHashImpl(hashCode, 0, pathCount + 1);
- //
- // if (m_pathFlags != null)
- // m_pathFlags.calculateHashImpl(hashCode, 0, pathCount);
- // }
- //
- // return hashCode;
- // }
-
@Override
public boolean equals(Object other) {
if (other == this)
@@ -2006,15 +1948,27 @@ public boolean equals(Object other) {
if (pathCount != pathCountOther)
return false;
- if (m_paths != null
+ if (pathCount > 0 && m_paths != null
&& !m_paths.equals(otherMultiPath.m_paths, 0, pathCount + 1))
return false;
- if (m_pathFlags != null
- && !m_pathFlags
- .equals(otherMultiPath.m_pathFlags, 0, pathCount))
+ if (m_fill_rule != otherMultiPath.m_fill_rule)
return false;
+ {
+ // Note: OGC flags do not participate in the equals operation by
+ // design.
+ // Because for the polygon pathFlags will have all enum_closed set,
+ // we do not need to compare this stream. Only for polyline.
+ // Polyline does not have OGC flags set.
+ if (!m_bPolygon) {
+ if (m_pathFlags != null
+ && !m_pathFlags.equals(otherMultiPath.m_pathFlags, 0,
+ pathCount))
+ return false;
+ }
+ }
+
return super.equals(other);
}
@@ -2026,7 +1980,6 @@ public boolean equals(Object other) {
*/
public SegmentIteratorImpl querySegmentIteratorAtVertex(int startVertexIndex) {
if (startVertexIndex < 0 || startVertexIndex >= getPointCount())
- // FIXME
throw new IndexOutOfBoundsException();
SegmentIteratorImpl iter = new SegmentIteratorImpl(this,
@@ -2180,26 +2133,34 @@ int getOGCPolygonCount() {
protected void _updateOGCFlags() {
if (_hasDirtyFlag(DirtyFlags.DirtyOGCFlags)) {
_updateRingAreas2D();
-
- int pathCount = getPathCount();
- if (m_pathFlags == null || m_pathFlags.size() < pathCount)
- m_pathFlags = (AttributeStreamOfInt8) AttributeStreamBase
- .createByteStream(pathCount + 1);
-
- int firstSign = 1;
- for (int ipath = 0; ipath < pathCount; ipath++) {
- double area = m_cachedRingAreas2D.read(ipath);
- if (ipath == 0) firstSign = area > 0 ? 1 : -1;
- if (area * firstSign > 0.0)
- m_pathFlags.setBits(ipath,
- (byte) PathFlags.enumOGCStartPolygon);
- else
- m_pathFlags.clearBits(ipath,
- (byte) PathFlags.enumOGCStartPolygon);
- }
+ _updateOGCFlagsHelper();
_setDirtyFlag(DirtyFlags.DirtyOGCFlags, false);
}
}
+
+ private void _updateOGCFlagsHelper() {
+ int pathCount = getPathCount();
+ if (pathCount > 0 && (m_pathFlags == null || m_pathFlags.size() < pathCount))
+ m_pathFlags = (AttributeStreamOfInt8) AttributeStreamBase.createByteStream(pathCount + 1);
+
+ // firstSign is the sign of first ring.
+ // a first ring with non zero area defines the
+ // value. First zero area rings are written out as enumOGCStartPolygon.
+ int firstSign = 0;
+ for (int ipath = 0; ipath < pathCount; ipath++) {
+ double area = m_cachedRingAreas2D.read(ipath);
+ if (firstSign == 0) {
+ // if the first ring is inverted we assume that the
+ // whole polygon is inverted.
+ firstSign = MathUtils.sign(area);
+ }
+
+ if (area * firstSign > 0.0 || firstSign == 0)
+ m_pathFlags.setBits(ipath, (byte) PathFlags.enumOGCStartPolygon);
+ else
+ m_pathFlags.clearBits(ipath, (byte) PathFlags.enumOGCStartPolygon);
+ }
+ }
public int getPathIndexFromPointIndex(int pointIndex) {
int positionHint = m_currentPathIndex;// in case of multithreading
@@ -2479,6 +2440,7 @@ public boolean _buildRasterizedGeometryAccelerator(double toleranceXY,
rgeom = RasterizedGeometry2D.create(this, toleranceXY, rasterSize);
m_accelerators._setRasterizedGeometry(rgeom);
+ //rgeom.dbgSaveToBitmap("c:/temp/ddd.bmp");
return true;
}
@@ -2524,11 +2486,11 @@ public void getSegment(int startVertexIndex, SegmentBuffer segBuffer,
segBuffer.createLine();
break;
case SegmentFlags.enumBezierSeg:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
case SegmentFlags.enumArcSeg:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
default:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
Segment currentSegment = segBuffer.get();
@@ -2590,6 +2552,30 @@ void queryPathEnvelope2D(int path_index, Envelope2D envelope) {
envelope.setCoords(env);
}
}
+
+ public void queryLoosePathEnvelope2D(int path_index, Envelope2D envelope) {
+ if (path_index >= getPathCount())
+ throw new IllegalArgumentException();
+
+ if (isEmpty()) {
+ envelope.setEmpty();
+ return;
+ }
+
+ if (hasNonLinearSegments(path_index)) {
+ throw new GeometryException("not implemented");
+ } else {
+ AttributeStreamOfDbl stream = (AttributeStreamOfDbl) getAttributeStreamRef(VertexDescription.Semantics.POSITION);
+ Point2D pt = new Point2D();
+ Envelope2D env = new Envelope2D();
+ env.setEmpty();
+ for (int i = getPathStart(path_index), iend = getPathEnd(path_index); i < iend; i++) {
+ stream.read(2 * i, pt);
+ env.merge(pt);
+ }
+ envelope.setCoords(env);
+ }
+ }
@Override
public boolean _buildQuadTreeAccelerator(GeometryAccelerationDegree d) {
@@ -2606,5 +2592,35 @@ public boolean _buildQuadTreeAccelerator(GeometryAccelerationDegree d) {
return true;
}
-
+
+ boolean _buildQuadTreeForPathsAccelerator(GeometryAccelerationDegree degree) {
+ if (m_accelerators == null) {
+ m_accelerators = new GeometryAccelerators();
+ }
+
+ // TODO: when less than two envelopes - no need to this.
+
+ if (m_accelerators.getQuadTreeForPaths() != null)
+ return true;
+
+ m_accelerators._setQuadTreeForPaths(null);
+ QuadTreeImpl quad_tree_impl = InternalUtils.buildQuadTreeForPaths(this);
+ m_accelerators._setQuadTreeForPaths(quad_tree_impl);
+
+ return true;
+ }
+
+ void setFillRule(int rule) {
+ assert (m_bPolygon);
+ m_fill_rule = rule;
+ }
+
+ int getFillRule() {
+ return m_fill_rule;
+ }
+
+ void clearDirtyOGCFlags() {
+ _setDirtyFlag(DirtyFlags.DirtyOGCFlags, false);
+ }
}
+
diff --git a/src/com/esri/core/geometry/MultiPoint.java b/src/main/java/com/esri/core/geometry/MultiPoint.java
similarity index 87%
rename from src/com/esri/core/geometry/MultiPoint.java
rename to src/main/java/com/esri/core/geometry/MultiPoint.java
index 0a7baf04..4beca5b5 100644
--- a/src/com/esri/core/geometry/MultiPoint.java
+++ b/src/main/java/com/esri/core/geometry/MultiPoint.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,13 +26,15 @@
import java.io.Serializable;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_MULTI_POINT;
+
/**
* A Multipoint is a collection of points. A multipoint is a one-dimensional
* geometry object. Multipoints can be used to store a collection of point-based
* information where the order and individual identity of each point is not an
* essential characteristic of the point set.
*/
-public final class MultiPoint extends MultiVertexGeometry implements
+public class MultiPoint extends MultiVertexGeometry implements
Serializable {
private static final long serialVersionUID = 2L;
@@ -76,7 +78,7 @@ public Point2D getXY(int index) {
}
@Override
- void getXY(int index, Point2D pt) {
+ public void getXY(int index, Point2D pt) {
m_impl.getXY(index, pt);
}
@@ -86,12 +88,12 @@ Point3D getXYZ(int index) {
}
@Override
- void queryCoordinates(Point2D[] dst) {
+ public void queryCoordinates(Point2D[] dst) {
m_impl.queryCoordinates(dst);
}
@Override
- void queryCoordinates(Point[] dst) {
+ public void queryCoordinates(Point[] dst) {
m_impl.queryCoordinates(dst);
}
@@ -122,6 +124,15 @@ public void add(double x, double y) {
m_impl.add(x, y);
}
+ /**
+ * Adds a point with the specified X, Y coordinates to this multipoint.
+ *
+ * @param pt the point to add
+ */
+ public void add(Point2D pt) {
+ m_impl.add(pt.x, pt.y);
+ }
+
/**
* Adds a 3DPoint with the specified X, Y, Z coordinates to this multipoint.
*
@@ -215,7 +226,7 @@ public void setPoint(int index, Point pointSrc) {
}
@Override
- void setXY(int index, Point2D pt) {
+ public void setXY(int index, Point2D pt) {
m_impl.setXY(index, pt);
}
@@ -249,6 +260,12 @@ public int getDimension() {
return 0;
}
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_MULTI_POINT + m_impl.estimateMemorySize();
+ }
+
@Override
public Geometry.Type getType() {
return Type.MultiPoint;
@@ -265,7 +282,7 @@ public void addAttribute(int semantics) {
}
@Override
- void assignVertexDescription(VertexDescription src) {
+ public void assignVertexDescription(VertexDescription src) {
m_impl.assignVertexDescription(src);
}
@@ -280,7 +297,7 @@ public void dropAttribute(int semantics) {
}
@Override
- void mergeVertexDescription(VertexDescription src) {
+ public void mergeVertexDescription(VertexDescription src) {
m_impl.mergeVertexDescription(src);
}
@@ -346,12 +363,12 @@ int queryCoordinates(Point2D[] dst, int dstSize, int beginIndex,
}
@Override
- void getPointByVal(int index, Point outPoint) {
+ public void getPointByVal(int index, Point outPoint) {
m_impl.getPointByVal(index, outPoint);
}
@Override
- void setPointByVal(int index, Point pointSrc) {
+ public void setPointByVal(int index, Point pointSrc) {
m_impl.setPointByVal(index, pointSrc);
}
@@ -359,4 +376,14 @@ void setPointByVal(int index, Point pointSrc) {
public int getStateFlag() {
return m_impl.getStateFlag();
}
+
+ @Override
+ public Geometry getBoundary() {
+ return m_impl.getBoundary();
+ }
+
+ @Override
+ public void replaceNaNs(int semantics, double value) {
+ m_impl.replaceNaNs(semantics, value);
+ }
}
diff --git a/src/com/esri/core/geometry/MultiPointImpl.java b/src/main/java/com/esri/core/geometry/MultiPointImpl.java
similarity index 94%
rename from src/com/esri/core/geometry/MultiPointImpl.java
rename to src/main/java/com/esri/core/geometry/MultiPointImpl.java
index 65d7ca48..bb16671f 100644
--- a/src/com/esri/core/geometry/MultiPointImpl.java
+++ b/src/main/java/com/esri/core/geometry/MultiPointImpl.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,11 +26,12 @@
import com.esri.core.geometry.VertexDescription.Semantics;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_MULTI_POINT_IMPL;
+
/**
* The MultiPoint is a collection of points.
*/
final class MultiPointImpl extends MultiVertexGeometryImpl {
-
public MultiPointImpl() {
super();
m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
@@ -247,6 +248,19 @@ public int getDimension() {
return 0;
}
+ @Override
+ public long estimateMemorySize()
+ {
+ long size = SIZE_OF_MULTI_POINT_IMPL + (m_envelope != null ? m_envelope.estimateMemorySize() : 0);
+
+ if (m_vertexAttributes != null) {
+ for (int i = 0; i < m_vertexAttributes.length; i++) {
+ size += m_vertexAttributes[i].estimateMemorySize();
+ }
+ }
+ return size;
+ }
+
@Override
public Geometry.Type getType() {
return Type.MultiPoint;
@@ -343,4 +357,9 @@ public boolean _buildQuadTreeAccelerator(GeometryAccelerationDegree accelDegree)
// // TODO Auto-generated method stub
//
// }
+
+ @Override
+ public Geometry getBoundary() {
+ return null;
+ }
}
diff --git a/src/com/esri/core/geometry/MultiVertexGeometry.java b/src/main/java/com/esri/core/geometry/MultiVertexGeometry.java
similarity index 87%
rename from src/com/esri/core/geometry/MultiVertexGeometry.java
rename to src/main/java/com/esri/core/geometry/MultiVertexGeometry.java
index cbbf9b9d..c164b48c 100644
--- a/src/com/esri/core/geometry/MultiVertexGeometry.java
+++ b/src/main/java/com/esri/core/geometry/MultiVertexGeometry.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -32,22 +32,14 @@
* The vertex attributes are stored in separate arrays of corresponding type.
* There are as many arrays as there are attributes in the vertex.
*/
-abstract class MultiVertexGeometry extends Geometry implements
+public abstract class MultiVertexGeometry extends Geometry implements
Serializable {
@Override
- void _afterAddAttributeImpl(int semantics) {
- // TODO Auto-generated method stub
-
+ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
+ throw new GeometryException("invalid call");
}
-
- @Override
- void _beforeDropAttributeImpl(int semantics) {
- // TODO Auto-generated method stub
-
- }
-
- // Multipart methods:
+
/**
* Returns the total vertex count in this Geometry.
*/
@@ -63,7 +55,7 @@ void _beforeDropAttributeImpl(int semantics) {
*/
public void getPoint(int index, Point ptOut) {
getPointByVal(index, ptOut);
- }// Java only
+ }
/**
* Sets the vertex at given index of the Geometry.
@@ -87,13 +79,13 @@ public void getPoint(int index, Point ptOut) {
*/
public abstract Point2D getXY(int index);
- abstract void getXY(int index, Point2D pt);
+ public abstract void getXY(int index, Point2D pt);
/**
* Sets XY coordinates of the given vertex of the Geometry. All other
* attributes are unchanged.
*/
- abstract void setXY(int index, Point2D pt);
+ public abstract void setXY(int index, Point2D pt);
/**
* Returns XYZ coordinates of the given vertex of the Geometry. If the
@@ -126,13 +118,13 @@ Point3D[] getCoordinates3D() {
return arr;
}
- abstract void queryCoordinates(Point[] dst);
+ public abstract void queryCoordinates(Point[] dst);
/**
* Queries XY coordinates as an array. The array must be larg enough (See
* GetPointCount()).
*/
- abstract void queryCoordinates(Point2D[] dst);
+ public abstract void queryCoordinates(Point2D[] dst);
/**
* Queries XYZ coordinates as an array. The array must be larg enough (See
@@ -154,7 +146,7 @@ Point3D[] getCoordinates3D() {
* If attribute is not present, the default value is returned.
* See VertexDescription::GetDefaultValue() method.
*/
- public abstract double getAttributeAsDbl(int semantics, int index,
+ abstract double getAttributeAsDbl(int semantics, int index,
int ordinate);
/**
@@ -172,7 +164,7 @@ public abstract double getAttributeAsDbl(int semantics, int index,
* See VertexDescription::GetDefaultValue() method. Avoid using
* this method on non-integer atributes.
*/
- public abstract int getAttributeAsInt(int semantics, int index, int ordinate);
+ abstract int getAttributeAsInt(int semantics, int index, int ordinate);
/**
* Sets the value of given attribute at given posisiotnsis.
@@ -190,7 +182,7 @@ public abstract double getAttributeAsDbl(int semantics, int index,
*
* If the attribute is not present in this Geometry, it is added.
*/
- public abstract void setAttribute(int semantics, int index, int ordinate,
+ abstract void setAttribute(int semantics, int index, int ordinate,
double value);
/**
@@ -198,14 +190,14 @@ public abstract void setAttribute(int semantics, int index, int ordinate,
* non-integer atributes because some double attributes may have NaN default
* values (e.g. Ms)
*/
- public abstract void setAttribute(int semantics, int index, int ordinate,
+ abstract void setAttribute(int semantics, int index, int ordinate,
int value);
/**
* Returns given vertex of the Geometry. The outPoint will have same
* VertexDescription as this Geometry.
*/
- abstract void getPointByVal(int index, Point outPoint);
+ public abstract void getPointByVal(int index, Point outPoint);
/**
* Sets the vertex at given index of the Geometry.
@@ -222,6 +214,6 @@ public abstract void setAttribute(int semantics, int index, int ordinate,
* the Geometry will be set to the default values (see
* VertexDescription::GetDefaultValue).
*/
- abstract void setPointByVal(int index, Point pointSrc);
+ public abstract void setPointByVal(int index, Point pointSrc);
}
diff --git a/src/com/esri/core/geometry/MultiVertexGeometryImpl.java b/src/main/java/com/esri/core/geometry/MultiVertexGeometryImpl.java
similarity index 83%
rename from src/com/esri/core/geometry/MultiVertexGeometryImpl.java
rename to src/main/java/com/esri/core/geometry/MultiVertexGeometryImpl.java
index 9b5ce354..e045aa2a 100644
--- a/src/com/esri/core/geometry/MultiVertexGeometryImpl.java
+++ b/src/main/java/com/esri/core/geometry/MultiVertexGeometryImpl.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -63,52 +63,34 @@ public interface GeometryXSimple {
protected abstract void _verifyStreamsImpl();
public interface DirtyFlags {
- public static final int DirtyIsKnownSimple = 1; // !<0 when IsWeakSimple
- // flag is valid
- public static final int IsWeakSimple = 2; // != m_pointCount)
// TODO
throw new GeometryException("index out of bounds");
- // _ASSERT(!IsEmpty());
- // _ASSERT(m_vertexAttributes != null);
-
_verifyAllStreams();
Point outPoint = dst;
outPoint.assignVertexDescription(m_description);
- if (outPoint.isEmpty())
- outPoint._setToDefault();
for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
@@ -212,9 +184,8 @@ void getPointByVal(int index, Point dst) {
}
}
- // Checked vs. Jan 11, 2011
@Override
- protected void setPointByVal(int index, Point src) {
+ public void setPointByVal(int index, Point src) {
if (index < 0 || index >= m_pointCount)
throw new GeometryException("index out of bounds");
@@ -292,12 +263,9 @@ public void setXY(int index, double x, double y) {
@Override
public Point3D getXYZ(int index) {
if (index < 0 || index >= getPointCount())
- // FIXME exc
throw new IndexOutOfBoundsException();
_verifyAllStreams();
- // AttributeStreamOfDbl v = (AttributeStreamOfDbl)
- // m_vertexAttributes[0];
AttributeStreamOfDbl v = (AttributeStreamOfDbl) m_vertexAttributes[0];
Point3D pt = new Point3D();
pt.x = v.read(index * 2);
@@ -316,15 +284,12 @@ public Point3D getXYZ(int index) {
@Override
public void setXYZ(int index, Point3D pt) {
if (index < 0 || index >= getPointCount())
- // FIXME exc
throw new IndexOutOfBoundsException();
addAttribute(Semantics.Z);
_verifyAllStreams();
notifyModified(DirtyFlags.DirtyCoordinates);
- // AttributeStreamOfDbl v = (AttributeStreamOfDbl)
- // m_vertexAttributes[0];
AttributeStreamOfDbl v = (AttributeStreamOfDbl) m_vertexAttributes[0];
v.write(index * 2, pt.x);
v.write(index * 2 + 1, pt.y);
@@ -335,12 +300,10 @@ public void setXYZ(int index, Point3D pt) {
@Override
public double getAttributeAsDbl(int semantics, int offset, int ordinate) {
if (offset < 0 || offset >= m_pointCount)
- // FIXME exc
throw new IndexOutOfBoundsException();
int ncomps = VertexDescription.getComponentCount(semantics);
if (ordinate >= ncomps)
- // FIXME exc
throw new IndexOutOfBoundsException();
_verifyAllStreams();
@@ -366,12 +329,10 @@ public int getAttributeAsInt(int semantics, int offset, int ordinate) {
public void setAttribute(int semantics, int offset, int ordinate,
double value) {
if (offset < 0 || offset >= m_pointCount)
- // FIXME exc
throw new IndexOutOfBoundsException();
int ncomps = VertexDescription.getComponentCount(semantics);
if (ordinate >= ncomps)
- // FIXME exc
throw new IndexOutOfBoundsException();
addAttribute(semantics);
@@ -388,8 +349,6 @@ public void setAttribute(int semantics, int offset, int ordinate, int value) {
setAttribute(semantics, offset, ordinate, (double) value);
}
- // FIXME change semantics to an enum
- // Checked vs. Jan 11, 2011
public AttributeStreamBase getAttributeStreamRef(int semantics) {
throwIfEmpty();
@@ -400,8 +359,6 @@ public AttributeStreamBase getAttributeStreamRef(int semantics) {
return m_vertexAttributes[attributeIndex];
}
- // FIXME change semantics to an enum
- // Checked vs. Jan 11, 2011
/**
* Sets a reference to the given AttributeStream of the Geometry. Once the
* buffer has been obtained, the vertices of the Geometry can be manipulated
@@ -424,7 +381,6 @@ public void setAttributeStreamRef(int semantics, AttributeStreamBase stream) {
if ((stream != null)
&& VertexDescription.getPersistence(semantics) != stream
.getPersistence())// input stream has wrong persistence
- // FIXME exc
throw new IllegalArgumentException();
// Do not check for the stream size here to allow several streams to be
@@ -439,59 +395,35 @@ public void setAttributeStreamRef(int semantics, AttributeStreamBase stream) {
notifyModified(DirtyFlags.DirtyAll);
}
- // Checked vs. Jan 11, 2011
- @Override
- void _beforeDropAttributeImpl(int semantics) {
- _touch();
- int attributeIndex = m_description.getAttributeIndex(semantics);
- // _ASSERT(attributeIndex >= 0);
-
- AttributeStreamBase[] newAttributes = null;
- if (m_vertexAttributes != null) {
- newAttributes = new AttributeStreamBase[m_description
- .getAttributeCount() - 1];
-
- for (int i = 0; i < attributeIndex; i++)
- newAttributes[i] = m_vertexAttributes[i];
- for (int i = attributeIndex + 1; i < m_description
- .getAttributeCount(); i++)
- newAttributes[i - 1] = m_vertexAttributes[i];
- }
-
- m_vertexAttributes = newAttributes; // late assignment to try to stay
- // valid if out-of memory happens.
- notifyModified(DirtyFlags.DirtyAll);
- }
-
- // Checked vs. Jan 11, 2011
@Override
- void _afterAddAttributeImpl(int semantics) {
- _touch();
- int attributeIndex = m_description.getAttributeIndex(semantics);
- // _ASSERT(attributeIndex >= 0);
-
+ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
AttributeStreamBase[] newAttributes = null;
+
if (m_vertexAttributes != null) {
- newAttributes = new AttributeStreamBase[m_description
- .getAttributeCount()];
+ int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(
+ newDescription, m_description);
+
+ newAttributes = new AttributeStreamBase[newDescription
+ .getAttributeCount()];
+
+ for (int i = 0, n = newDescription.getAttributeCount(); i < n; i++) {
+ if (mapping[i] != -1) {
+ int m = mapping[i];
+ newAttributes[i] = m_vertexAttributes[m];
+ }
- if (m_vertexAttributes != null) {
- // Do not create new stream The stream will be created when one
- // queries or sets a point to it.
- for (int i = 0; i < attributeIndex; i++)
- newAttributes[i] = m_vertexAttributes[i];
- for (int i = attributeIndex + 1; i < m_description
- .getAttributeCount(); i++)
- newAttributes[i] = m_vertexAttributes[i - 1];
}
}
-
+ else {
+ //if there are no streams we do not create them
+ }
+
+ m_description = newDescription;
m_vertexAttributes = newAttributes; // late assignment to try to stay
- // valid if out-of memory happens.
m_reservedPointCount = -1;// we need to recreate the new attribute then
notifyModified(DirtyFlags.DirtyAll);
}
-
+
// Checked vs. Jan 11, 2011
protected void _updateEnvelope(Envelope2D env) {
_updateAllDirtyIntervals(true);
@@ -600,7 +532,6 @@ public boolean equals(Object other) {
if (!(other instanceof MultiVertexGeometryImpl))
return false;
- // Borg Implementation
MultiVertexGeometryImpl otherMulti = (MultiVertexGeometryImpl) other;
if (!(m_description.equals(otherMulti.m_description)))
@@ -641,7 +572,6 @@ public boolean equals(Object other) {
*/
public void setEnvelope(Envelope env) {
if (!m_description.equals(env.getDescription()))
- // FIXME exc
throw new IllegalArgumentException();
// m_envelope = (Envelope) env.clone();
@@ -690,15 +620,10 @@ void _copyToUnsafe(MultiVertexGeometryImpl dst) {
dst.m_flagsMask = m_flagsMask;
dst.m_vertexAttributes = cloneAttributes;
- // FIXME accelerators
- // if(m_accelerators != null)
- // dst.m_accelerators = m_accelerators;
-
try {
_copyToImpl(dst); // copy child props
} catch (Exception ex) {
dst.setEmpty();
- // TODO fix exception
throw new RuntimeException(ex);
}
}
@@ -735,7 +660,6 @@ public void notifyModified(int flags) {
}
m_flagsMask |= flags;
- // FIXME acceler
_clearAccelerators();
_touch();
}
@@ -853,10 +777,6 @@ protected void _verifyAllStreamsImpl() {
m_vertexAttributes[attributeIndex] = AttributeStreamBase
.createAttributeStreamWithSemantics(semantics,
m_pointCount);
- // FIXME when attribute stream is updated, update this code.
- // m_vertexAttributes[attributeIndex] =
- // AttributeStreamBase.createAttributeStream(semantics,
- // m_pointCount);
m_reservedPointCount = m_pointCount;
}
}
@@ -879,7 +799,7 @@ void _resizeImpl(int pointCount) {
}
// Checked vs. Jan 11, 2011
- int QueryCoordinates(Point2D[] dst, int dstSize, int beginIndex,
+ int queryCoordinates(Point2D[] dst, int dstSize, int beginIndex,
int endIndex) {
int endIndexC = endIndex < 0 ? m_pointCount : endIndex;
endIndexC = Math.min(endIndexC, beginIndex + dstSize);
@@ -891,7 +811,7 @@ int QueryCoordinates(Point2D[] dst, int dstSize, int beginIndex,
AttributeStreamOfDbl xy = (AttributeStreamOfDbl) getAttributeStreamRef(VertexDescription.Semantics.POSITION);
int j = 0;
double[] dstArray = new double[dst.length * 2];
- xy.readRange(2 * beginIndex, endIndexC - beginIndex, dstArray, j, true);
+ xy.readRange(2 * beginIndex, (endIndexC - beginIndex) * 2, dstArray, j, true);
for (int i = 0; i < dst.length; i++) {
dst[i] = new Point2D(dstArray[i * 2], dstArray[i * 2 + 1]);
@@ -982,7 +902,7 @@ void setIsSimple(int isSimpleRes, double tolerance, boolean ogc_known) {
_setDirtyFlag(DirtyFlags.IsWeakSimple, true);
_setDirtyFlag(DirtyFlags.IsStrongSimple, true);
} else
- throw new GeometryException("internal error");// what?
+ throw GeometryException.GeometryInternalError();// what?
}
double _getSimpleTolerance() {
@@ -1011,9 +931,6 @@ void _interpolateTwoVertices(int vertex1, int vertex2, double f,
_verifyAllStreams();
outPoint.assignVertexDescription(m_description);
- if (outPoint.isEmpty())
- outPoint._setToDefault();
-
for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
int semantics = m_description._getSemanticsImpl(attributeIndex);
@@ -1023,7 +940,7 @@ void _interpolateTwoVertices(int vertex1, int vertex2, double f,
* vertex1 + icomp);
double v2 = m_vertexAttributes[attributeIndex].readAsDbl(ncomp
* vertex2 + icomp);
- outPoint.setAttribute(semantics, icomp, v1 * (1.0 - f) + v2 * f);
+ outPoint.setAttribute(semantics, icomp, MathUtils.lerp(v1, v2, f));
}
}
}
@@ -1034,47 +951,16 @@ void _interpolateTwoVertices(int vertex1, int vertex2, double f,
return pt.length();
}
- // FIXME Remove this method. It is not in the MultiVertexGeometryImpl...
-
- // /**
- // * Returns a reference to the given AttributeStream of the Geometry. Once
- // * the stream has been obtained, the vertices of the Geometry can be
- // * manipulated directly. Call notifyModified, when finished. The method
- // * allocates the stream if not present.
- // *
- // * @param semantics
- // * Semantics of the attribute to return stream for.
- // * @throws Throws
- // * empty_geometry for the empty geometry.
- // */
- // public AttributeStreamBase getAttributeStream(int semantics) {
- // if (isEmpty())
- // throw new GeometryException(
- // "This operation was performed on an Empty Geometry.");
- //
- // addAttribute(semantics);
- // _verifyAllStreams();
- //
- // int attributeIndex = m_description.getAttributeIndex(semantics);
- // return m_vertexAttributes[attributeIndex];
- // }
-
- // FIXME
// ////////////////// METHODS To REMOVE ///////////////////////
@Override
public Point getPoint(int index) {
if (index < 0 || index >= m_pointCount)
throw new IndexOutOfBoundsException();
- // _ASSERT(!IsEmpty());
- // _ASSERT(m_vertexAttributes != null);
-
_verifyAllStreams();
Point outPoint = new Point();
outPoint.assignVertexDescription(m_description);
- if (outPoint.isEmpty())
- outPoint._setToDefault();
for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
@@ -1148,14 +1034,51 @@ public void queryCoordinates(Point3D[] dst) {
dst[i] = getXYZ(i);
}
}
-
- // FIXME
+
+ @Override
+ public void replaceNaNs(int semantics, double value) {
+ addAttribute(semantics);
+ if (isEmpty())
+ return;
+
+ boolean modified = false;
+ int ncomps = VertexDescription.getComponentCount(semantics);
+ for (int i = 0; i < ncomps; i++) {
+ AttributeStreamBase streamBase = getAttributeStreamRef(semantics);
+ if (streamBase instanceof AttributeStreamOfDbl) {
+ AttributeStreamOfDbl dblStream = (AttributeStreamOfDbl)streamBase;
+ for (int ivert = 0, n = m_pointCount * ncomps; ivert < n; ivert++) {
+ double v = dblStream.read(ivert);
+ if (Double.isNaN(v)) {
+ dblStream.write(ivert, value);
+ modified = true;
+ }
+ }
+ }
+ else {
+ for (int ivert = 0, n = m_pointCount * ncomps; ivert < n; ivert++) {
+ double v = streamBase.readAsDbl(ivert);
+ if (Double.isNaN(v)) {
+ streamBase.writeAsDbl(ivert, value);
+ modified = true;
+ }
+ }
+ }
+ }
+
+ if (modified) {
+ notifyModified(DirtyFlags.DirtyCoordinates);
+ }
+ }
public abstract boolean _buildRasterizedGeometryAccelerator(
double toleranceXY, GeometryAccelerationDegree accelDegree);
public abstract boolean _buildQuadTreeAccelerator(
GeometryAccelerationDegree d);
- // //////////////////METHODS To REMOVE ///////////////////////
+ @Override
+ public String toString() {
+ return "MultiVertexGeometryImpl";
+ }
}
diff --git a/src/main/java/com/esri/core/geometry/NonSimpleResult.java b/src/main/java/com/esri/core/geometry/NonSimpleResult.java
new file mode 100644
index 00000000..87d95111
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/NonSimpleResult.java
@@ -0,0 +1,108 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+/**
+ * The result of the IsSimpleXXX.
+ *
+ *
+ */
+public class NonSimpleResult {
+ public enum Reason {
+ /**
+ *This value is returned if the geometry "knows" through an internal state that it is non-simple.
+ *To make it determine the reason, use
+ *bForceTest == True.
+ */
+ NotDetermined,
+ /**
+ * non-simple, because the structure is bad (0 size path, for example).
+ */
+ Structure,
+ /**
+ * Non-simple, because there are degenerate segments.
+ */
+ DegenerateSegments,
+ /**
+ * Non-simple, because not clustered properly, that is there are non-coincident vertices closer than tolerance.
+ */
+ Clustering,
+ /**
+ * Non-simple, because not cracked properly (intersecting segments, overlaping segments)
+ */
+ Cracking,
+ /**
+ * Non-simple, because there are crossovers (self intersections that are not cracking case).
+ */
+ CrossOver,
+ /**
+ * Non-simple, because holes or exteriors have wrong orientation.
+ */
+ RingOrientation,
+ /**
+ *The geometry is simple, but not strong-simple, because exteriors
+ *and holes are not in the correct order, and separation into sub polygons is not possible.
+ *Geometry needs to be resimplified with the bForceTest = true to fix this.
+ */
+ RingOrder,
+ /**
+ * There is a self tangency or cross-over situation (strong simple, but not OGC simple)
+ * Only OperatorSimplifyOGC returns this.
+ */
+ OGCPolylineSelfTangency,
+ /**
+ * There is a self tangency situation (strong simple, but not OGC simple)
+ * Only OperatorSimplifyOGC returns this.
+ */
+ OGCPolygonSelfTangency,
+ /**
+ * Touching interioir rings make a disconnected point set from polygon interior
+ * (strong simple, but not OGC simple).
+ * Only OperatorSimplifyOGC returns this.
+ */
+ OGCDisconnectedInterior
+ }
+
+ public Reason m_reason;
+ public int m_vertexIndex1;
+ public int m_vertexIndex2;
+
+ public NonSimpleResult() {
+ m_reason = Reason.NotDetermined;
+ m_vertexIndex1 = -1;
+ m_vertexIndex2 = -1;
+ }
+
+ void Assign(NonSimpleResult src) {
+ m_reason = src.m_reason;
+ m_vertexIndex1 = src.m_vertexIndex1;
+ m_vertexIndex2 = src.m_vertexIndex2;
+ }
+
+ NonSimpleResult(Reason reason, int index1, int index2) {
+ m_reason = reason;
+ m_vertexIndex1 = index1;
+ m_vertexIndex2 = index2;
+ }
+}
diff --git a/src/com/esri/core/geometry/NumberUtils.java b/src/main/java/com/esri/core/geometry/NumberUtils.java
similarity index 60%
rename from src/com/esri/core/geometry/NumberUtils.java
rename to src/main/java/com/esri/core/geometry/NumberUtils.java
index 7e540f0d..01b6fd92 100644
--- a/src/com/esri/core/geometry/NumberUtils.java
+++ b/src/main/java/com/esri/core/geometry/NumberUtils.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,13 +24,13 @@
package com.esri.core.geometry;
-class NumberUtils {
+public class NumberUtils {
- static int snap(int v, int minv, int maxv) {
+ public static int snap(int v, int minv, int maxv) {
return v < minv ? minv : v > maxv ? maxv : v;
}
- static long snap(long v, long minv, long maxv) {
+ public static long snap(long v, long minv, long maxv) {
return v < minv ? minv : v > maxv ? maxv : v;
}
@@ -38,47 +38,43 @@ public static double snap(double v, double minv, double maxv) {
return v < minv ? minv : v > maxv ? maxv : v;
}
- public static int sizeOf(double v) {
+ static int sizeOf(double v) {
return 8;
}
- public static int sizeOfDouble() {
+ static int sizeOfDouble() {
return 8;
}
- public static int sizeOf(int v) {
+ static int sizeOf(int v) {
return 4;
}
- public static int sizeOf(long v) {
+ static int sizeOf(long v) {
return 8;
}
- public static int sizeOf(byte v) {
+ static int sizeOf(byte v) {
return 1;
}
- public static boolean isNaN(double d) {
+ static boolean isNaN(double d) {
return Double.isNaN(d);
}
- public final static double TheNaN = Double.NaN;
+ final static double TheNaN = Double.NaN;
- public static double NaN() {
+ static double NaN() {
return Double.NaN;
}
- // public static void main(String[] args)
- // {
- // System.out.println(Long.toHexString(Double.doubleToLongBits(Double.NaN)));
- // System.out.println(Double.longBitsToDouble(0x7FF8000000000001L));
- //
- // System.out.println(Long.toHexString(Double.doubleToLongBits(Double.NEGATIVE_INFINITY)));
- // System.out.println(Double.longBitsToDouble(0xFFF8000000000000L));
- // System.out.println(Double.NEGATIVE_INFINITY);
- // }
-
- public static int hash(int n) {
+ //combines two hash values
+ public static int hashCombine(int hash1, int hash2) {
+ return (hash1 * 31 + hash2) & 0x7FFFFFFF;
+ }
+
+ //makes a hash out of an int
+ static int hash(int n) {
int hash = 5381;
hash = ((hash << 5) + hash) + (n & 0xFF); /* hash * 33 + c */
hash = ((hash << 5) + hash) + ((n >> 8) & 0xFF);
@@ -88,13 +84,15 @@ public static int hash(int n) {
return hash;
}
- public static int hash(double d) {
+ // //makes a hash out of an double
+ static int hash(double d) {
long bits = Double.doubleToLongBits(d);
int hc = (int) (bits ^ (bits >>> 32));
return hash(hc);
}
- public static int hash(int hashIn, int n) {
+ //adds an int to a hash value
+ static int hash(int hashIn, int n) {
int hash = ((hashIn << 5) + hashIn) + (n & 0xFF); /* hash * 33 + c */
hash = ((hash << 5) + hash) + ((n >> 8) & 0xFF);
hash = ((hash << 5) + hash) + ((n >> 16) & 0xFF);
@@ -103,39 +101,53 @@ public static int hash(int hashIn, int n) {
return hash;
}
- public static int hash(int hash, double d) {
+ //adds a double to a hash value
+ static int hash(int hash, double d) {
long bits = Double.doubleToLongBits(d);
int hc = (int) (bits ^ (bits >>> 32));
return hash(hash, hc);
}
- public static long doubleToInt64Bits(double d) {
+ static long doubleToInt64Bits(double d) {
return Double.doubleToLongBits(d);
}
- public static double negativeInf() {
+ static double negativeInf() {
return Double.NEGATIVE_INFINITY;
}
- public static double positiveInf() {
+ static double positiveInf() {
return Double.POSITIVE_INFINITY;
}
- public static int intMax() {
+ static int intMax() {
return Integer.MAX_VALUE;
}
- public static double doubleEps() {
+ static double doubleEps() {
return 2.2204460492503131e-016;
}
- public static double doubleMax() {
+ static double doubleMax() {
return Double.MAX_VALUE;
}
- public static int nextRand(int prevRand) {
+ static int nextRand(int prevRand) {
return (1103515245 * prevRand + 12345) & intMax(); // according to Wiki,
// this is gcc's
}
+
+ /**
+ * Returns true if two values are equal (also can compare inf and nan).
+ */
+ static boolean isEqualNonIEEE(double a, double b) {
+ return a == b || (Double.isNaN(a) && Double.isNaN(b));
+ }
+ /**
+ * Returns true if two values are equal (also can compare inf and nan).
+ */
+ static boolean isEqualNonIEEE(double a, double b, double tolerance) {
+ return a == b || Math.abs(a - b) <= tolerance || (Double.isNaN(a) && Double.isNaN(b));
+ }
}
diff --git a/src/com/esri/core/geometry/OGCStructure.java b/src/main/java/com/esri/core/geometry/OGCStructure.java
similarity index 97%
rename from src/com/esri/core/geometry/OGCStructure.java
rename to src/main/java/com/esri/core/geometry/OGCStructure.java
index 14dde139..9f0875b9 100644
--- a/src/com/esri/core/geometry/OGCStructure.java
+++ b/src/main/java/com/esri/core/geometry/OGCStructure.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/OGCStructureInternal.java b/src/main/java/com/esri/core/geometry/OGCStructureInternal.java
new file mode 100644
index 00000000..59cf1e61
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OGCStructureInternal.java
@@ -0,0 +1,82 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+//An internal helper class. Do not use.
+public class OGCStructureInternal {
+ private static class EditShapeCursor extends GeometryCursor {
+ EditShape m_shape;
+ int m_geom;
+ int m_index;
+
+ EditShapeCursor(EditShape shape, int index) {
+ m_shape = shape;
+ m_geom = -1;
+ m_index = index;
+ }
+ @Override
+ public Geometry next() {
+ if (m_shape != null) {
+ if (m_geom == -1)
+ m_geom = m_shape.getFirstGeometry();
+ else
+ m_geom = m_shape.getNextGeometry(m_geom);
+
+ if (m_geom == -1) {
+ m_shape = null;
+ }
+ else {
+ return m_shape.getGeometry(m_geom);
+ }
+
+ }
+
+ return null;
+ }
+
+ @Override
+ public int getGeometryID() {
+ return m_shape.getGeometryUserIndex(m_geom, m_index);
+ }
+
+ };
+
+ public static GeometryCursor prepare_for_ops_(GeometryCursor geoms, SpatialReference sr) {
+ assert(geoms != null);
+ EditShape editShape = new EditShape();
+ int geomIndex = editShape.createGeometryUserIndex();
+ for (Geometry g = geoms.next(); g != null; g = geoms.next()) {
+ int egeom = editShape.addGeometry(g);
+ editShape.setGeometryUserIndex(egeom, geomIndex, geoms.getGeometryID());
+ }
+
+ Envelope2D env = editShape.getEnvelope2D();
+ double tolerance = InternalUtils.calculateToleranceFromGeometry(sr,
+ env, true);
+
+ CrackAndCluster.execute(editShape, tolerance, null, true);
+ return OperatorSimplifyOGC.local().execute(new EditShapeCursor(editShape, geomIndex), sr, false, null);
+ }
+}
+
diff --git a/src/com/esri/core/geometry/ObjectCacheTable.java b/src/main/java/com/esri/core/geometry/ObjectCacheTable.java
similarity index 98%
rename from src/com/esri/core/geometry/ObjectCacheTable.java
rename to src/main/java/com/esri/core/geometry/ObjectCacheTable.java
index b655ed70..54b18abd 100644
--- a/src/com/esri/core/geometry/ObjectCacheTable.java
+++ b/src/main/java/com/esri/core/geometry/ObjectCacheTable.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/Operator.java b/src/main/java/com/esri/core/geometry/Operator.java
similarity index 85%
rename from src/com/esri/core/geometry/Operator.java
rename to src/main/java/com/esri/core/geometry/Operator.java
index 691c47f3..6866fb16 100644
--- a/src/com/esri/core/geometry/Operator.java
+++ b/src/main/java/com/esri/core/geometry/Operator.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -33,22 +33,21 @@ public abstract class Operator {
* The operator type enum.
*/
public enum Type {
- Project, // = 10300,// m_cuts = null;
+
+ OperatorCutCursor(boolean bConsiderTouch, Geometry cuttee, Polyline cutter,
+ SpatialReference spatialReference, ProgressTracker progressTracker) {
+ if (cuttee == null || cutter == null)
+ throw new GeometryException("invalid argument");
+
+ m_bConsiderTouch = bConsiderTouch;
+ m_cuttee = cuttee;
+ m_cutter = cutter;
+ Envelope2D e = InternalUtils.getMergedExtent(cuttee, cutter);
+ m_tolerance = InternalUtils.calculateToleranceFromGeometry(spatialReference, e, true);
+ m_cutIndex = -1;
+ m_progressTracker = progressTracker;
+ }
+
+ @Override
+ public int getGeometryID() {
+ return 0;
+ }
+
+ @Override
+ public Geometry next() {
+ generateCuts_();
+ if (++m_cutIndex < m_cuts.size()) {
+ return (Geometry)m_cuts.get(m_cutIndex);
+ }
+
+ return null;
+ }
+
+ private void generateCuts_() {
+ if (m_cuts != null)
+ return;
+
+ m_cuts = new ArrayList();
+
+ Geometry.Type type = m_cuttee.getType();
+ switch (type.value()) {
+ case Geometry.GeometryType.Polyline:
+ generate_polyline_cuts_();
+ break;
+
+ case Geometry.GeometryType.Polygon:
+ generate_polygon_cuts_();
+ break;
+
+ default:
+ break; // warning fix
+ }
+ }
+
+ private void generate_polyline_cuts_() {
+ MultiPath left = new Polyline();
+ MultiPath right = new Polyline();
+ MultiPath uncut = new Polyline();
+
+ m_cuts.add(left);
+ m_cuts.add(right);
+
+ ArrayList cutPairs = new ArrayList(
+ 0);
+ Cutter.CutPolyline(m_bConsiderTouch, (Polyline) m_cuttee, m_cutter,
+ m_tolerance, cutPairs, null, m_progressTracker);
+
+ for (int icut = 0; icut < cutPairs.size(); icut++) {
+ OperatorCutLocal.CutPair cutPair = cutPairs.get(icut);
+ if (cutPair.m_side == Side.Left) {
+ left.add((MultiPath) cutPair.m_geometry, false);
+ } else if (cutPair.m_side == Side.Right
+ || cutPair.m_side == Side.Coincident) {
+ right.add((MultiPath) cutPair.m_geometry, false);
+ } else if (cutPair.m_side == Side.Undefined) {
+ m_cuts.add((MultiPath) cutPair.m_geometry);
+ } else {
+ uncut.add((MultiPath) cutPair.m_geometry, false);
+ }
+ }
+
+ if (!uncut.isEmpty()
+ && (!left.isEmpty() || !right.isEmpty() || m_cuts.size() >= 3))
+ m_cuts.add(uncut);
+
+ if (left.isEmpty() && right.isEmpty() && m_cuts.size() < 3)
+ m_cuts.clear(); // no cuts
+ }
+
+ private void generate_polygon_cuts_() {
+ AttributeStreamOfInt32 cutHandles = new AttributeStreamOfInt32(0);
+ EditShape shape = new EditShape();
+ int sideIndex = shape.createGeometryUserIndex();
+ int cutteeHandle = shape.addGeometry(m_cuttee);
+ int cutterHandle = shape.addGeometry(m_cutter);
+ TopologicalOperations topoOp = new TopologicalOperations();
+ try {
+ topoOp.setEditShapeCrackAndCluster(shape, m_tolerance,
+ m_progressTracker);
+ topoOp.cut(sideIndex, cutteeHandle, cutterHandle, cutHandles);
+ Polygon cutteeRemainder = (Polygon) shape.getGeometry(cutteeHandle);
+
+ MultiPath left = new Polygon();
+ MultiPath right = new Polygon();
+
+ m_cuts.clear();
+ m_cuts.add(left);
+ m_cuts.add(right);
+
+ for (int icutIndex = 0; icutIndex < cutHandles.size(); icutIndex++) {
+ Geometry cutGeometry;
+ {
+ // intersection
+ EditShape shapeIntersect = new EditShape();
+ int geometryA = shapeIntersect.addGeometry(cutteeRemainder);
+ int geometryB = shapeIntersect.addGeometry(shape
+ .getGeometry(cutHandles.get(icutIndex)));
+ topoOp.setEditShape(shapeIntersect, m_progressTracker);
+ int intersectHandle = topoOp.intersection(geometryA,
+ geometryB);
+ cutGeometry = shapeIntersect.getGeometry(intersectHandle);
+
+ if (cutGeometry.isEmpty())
+ continue;
+
+ int side = shape.getGeometryUserIndex(
+ cutHandles.get(icutIndex), sideIndex);
+ if (side == 2)
+ left.add((MultiPath) cutGeometry, false);
+ else if (side == 1)
+ right.add((MultiPath) cutGeometry, false);
+ else
+ m_cuts.add((MultiPath) cutGeometry); // Undefined
+ }
+
+ {
+ // difference
+ EditShape shapeDifference = new EditShape();
+ int geometryA = shapeDifference
+ .addGeometry(cutteeRemainder);
+ int geometryB = shapeDifference.addGeometry(shape
+ .getGeometry(cutHandles.get(icutIndex)));
+ topoOp.setEditShape(shapeDifference, m_progressTracker);
+ cutteeRemainder = (Polygon) shapeDifference
+ .getGeometry(topoOp
+ .difference(geometryA, geometryB));
+ }
+ }
+
+ if (!cutteeRemainder.isEmpty() && cutHandles.size() > 0)
+ m_cuts.add((MultiPath) cutteeRemainder);
+
+ if (left.isEmpty() && right.isEmpty())
+ m_cuts.clear(); // no cuts
+
+ } finally {
+ topoOp.removeShape();
+ }
+ }
+}
+
diff --git a/src/com/esri/core/geometry/OperatorCutLocal.java b/src/main/java/com/esri/core/geometry/OperatorCutLocal.java
similarity index 99%
rename from src/com/esri/core/geometry/OperatorCutLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorCutLocal.java
index 98613301..75dccf2c 100644
--- a/src/com/esri/core/geometry/OperatorCutLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorCutLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorDensifyByLength.java b/src/main/java/com/esri/core/geometry/OperatorDensifyByLength.java
similarity index 94%
rename from src/com/esri/core/geometry/OperatorDensifyByLength.java
rename to src/main/java/com/esri/core/geometry/OperatorDensifyByLength.java
index c01ec80d..d9d9d692 100644
--- a/src/com/esri/core/geometry/OperatorDensifyByLength.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDensifyByLength.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public Type getType() {
* After that the curves are replaced with straight segments.
* @param progressTracker
* @return Returns the densified geometries (It does nothing to geometries
- * with dim < 1, but simply passes them along).
+ * with dim < 1, but simply passes them along).
*/
public abstract GeometryCursor execute(GeometryCursor inputGeometries,
double maxLength, ProgressTracker progressTracker);
@@ -67,7 +67,7 @@ public abstract GeometryCursor execute(GeometryCursor inputGeometries,
* After that the curves are replaced with straight segments.
* @param progressTracker
* @return Returns the densified geometry. (It does nothing to geometries
- * with dim < 1, but simply passes them along).
+ * with dim < 1, but simply passes them along).
*/
public abstract Geometry execute(Geometry inputGeometry, double maxLength,
ProgressTracker progressTracker);
diff --git a/src/com/esri/core/geometry/OperatorDensifyByLengthCursor.java b/src/main/java/com/esri/core/geometry/OperatorDensifyByLengthCursor.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorDensifyByLengthCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorDensifyByLengthCursor.java
index d876a60c..3a7267aa 100644
--- a/src/com/esri/core/geometry/OperatorDensifyByLengthCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDensifyByLengthCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -72,7 +72,7 @@ else if (geometryType == Geometry.GeometryType.Envelope)
return densifyEnvelope((Envelope) geom);
else
// TODO fix geometry exception to match native implementation
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);
// unreachable in java
// return null;
diff --git a/src/com/esri/core/geometry/OperatorDensifyByLengthLocal.java b/src/main/java/com/esri/core/geometry/OperatorDensifyByLengthLocal.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorDensifyByLengthLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorDensifyByLengthLocal.java
index dbffbf4b..f6eb5e0a 100644
--- a/src/com/esri/core/geometry/OperatorDensifyByLengthLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDensifyByLengthLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorDifference.java b/src/main/java/com/esri/core/geometry/OperatorDifference.java
similarity index 95%
rename from src/com/esri/core/geometry/OperatorDifference.java
rename to src/main/java/com/esri/core/geometry/OperatorDifference.java
index 1dbfc9ec..5e4b40e6 100644
--- a/src/com/esri/core/geometry/OperatorDifference.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDifference.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
/**
* Difference of geometries.
*/
-public abstract class OperatorDifference extends Operator {
+public abstract class OperatorDifference extends Operator implements CombineOperator {
@Override
public Type getType() {
diff --git a/src/com/esri/core/geometry/OperatorDifferenceCursor.java b/src/main/java/com/esri/core/geometry/OperatorDifferenceCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorDifferenceCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorDifferenceCursor.java
index 021d1512..8c2419af 100644
--- a/src/com/esri/core/geometry/OperatorDifferenceCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDifferenceCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorDifferenceLocal.java b/src/main/java/com/esri/core/geometry/OperatorDifferenceLocal.java
similarity index 88%
rename from src/com/esri/core/geometry/OperatorDifferenceLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorDifferenceLocal.java
index 2121729b..31db5027 100644
--- a/src/com/esri/core/geometry/OperatorDifferenceLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDifferenceLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -81,10 +81,6 @@ static Geometry difference(Geometry geometry_a, Geometry geometry_b,
if (!env_a_inflated.isIntersecting(env_b))
return geometry_a;
- if (dimension_a == 1 && dimension_b == 2)
- return polylineMinusArea_(geometry_a, geometry_b, type_b,
- spatial_reference, progress_tracker);
-
if (type_a == Geometry.GeometryType.Point) {
Geometry geometry_b_;
if (MultiPath.isSegment(type_b)) {
@@ -357,36 +353,5 @@ static Geometry multiPointMinusPoint_(MultiPoint multi_point, Point point,
return new_multipoint;
}
-
- static Geometry polylineMinusArea_(Geometry geometry, Geometry area,
- int area_type, SpatialReference sr, ProgressTracker progress_tracker) {
- // construct the complement of the Polygon (or Envelope)
- Envelope envelope = new Envelope();
- geometry.queryEnvelope(envelope);
- Envelope2D env_2D = new Envelope2D();
- area.queryEnvelope2D(env_2D);
- envelope.merge(env_2D);
- double dw = 0.1 * envelope.getWidth();
- double dh = 0.1 * envelope.getHeight();
- envelope.inflate(dw, dh);
-
- Polygon complement = new Polygon();
- complement.addEnvelope(envelope, false);
-
- MultiPathImpl complementImpl = (MultiPathImpl) (complement._getImpl());
-
- if (area_type == Geometry.GeometryType.Polygon) {
- MultiPathImpl polygonImpl = (MultiPathImpl) (area._getImpl());
- complementImpl.add(polygonImpl, true);
- } else
- complementImpl.addEnvelope((Envelope) (area), true);
-
- OperatorFactoryLocal projEnv = OperatorFactoryLocal.getInstance();
- OperatorIntersection operatorIntersection = (OperatorIntersection) projEnv
- .getOperator(Operator.Type.Intersection);
- Geometry difference = operatorIntersection.execute(geometry,
- complement, sr, progress_tracker);
- return difference;
- }
-
}
+
diff --git a/src/com/esri/core/geometry/OperatorDisjoint.java b/src/main/java/com/esri/core/geometry/OperatorDisjoint.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorDisjoint.java
rename to src/main/java/com/esri/core/geometry/OperatorDisjoint.java
index 9892661b..9404759f 100644
--- a/src/com/esri/core/geometry/OperatorDisjoint.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDisjoint.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorDisjointLocal.java b/src/main/java/com/esri/core/geometry/OperatorDisjointLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorDisjointLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorDisjointLocal.java
index e65c0b3e..5bbaa1a2 100644
--- a/src/com/esri/core/geometry/OperatorDisjointLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDisjointLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorDistance.java b/src/main/java/com/esri/core/geometry/OperatorDistance.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorDistance.java
rename to src/main/java/com/esri/core/geometry/OperatorDistance.java
index 206bbf93..d29c2c43 100644
--- a/src/com/esri/core/geometry/OperatorDistance.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDistance.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorDistanceLocal.java b/src/main/java/com/esri/core/geometry/OperatorDistanceLocal.java
similarity index 93%
rename from src/com/esri/core/geometry/OperatorDistanceLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorDistanceLocal.java
index 12bc7c48..9cb35c69 100644
--- a/src/com/esri/core/geometry/OperatorDistanceLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorDistanceLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -41,6 +41,9 @@ public double execute(Geometry geom1, Geometry geom2,
Geometry geometryA = geom1;
Geometry geometryB = geom2;
+ if (geometryA.isEmpty() || geometryB.isEmpty())
+ return NumberUtils.TheNaN;
+
Polygon polygonA;
Polygon polygonB;
MultiPoint multiPointA;
@@ -49,23 +52,41 @@ public double execute(Geometry geom1, Geometry geom2,
// if geometryA is an envelope use a polygon instead (if geom1 was
// folded, then geometryA will already be a polygon)
// if geometryA is a point use a multipoint instead
- if (geometryA.getType().equals(Geometry.Type.Point)) {
+ Geometry.Type gtA = geometryA.getType();
+ Geometry.Type gtB = geometryB.getType();
+ if (gtA == Geometry.Type.Point) {
+ if (gtB == Geometry.Type.Point) {
+ return Point2D.distance(((Point)geometryA).getXY(), ((Point)geometryB).getXY());
+ }
+ else if (gtB == Geometry.Type.Envelope) {
+ Envelope2D envB = new Envelope2D();
+ geometryB.queryEnvelope2D(envB);
+ return envB.distance(((Point)geometryA).getXY());
+ }
+
multiPointA = new MultiPoint();
multiPointA.add((Point) geometryA);
geometryA = multiPointA;
- } else if (geometryA.getType().equals(Geometry.Type.Envelope)) {
+ } else if (gtA == Geometry.Type.Envelope) {
+ if (gtB == Geometry.Type.Envelope) {
+ Envelope2D envA = new Envelope2D();
+ geometryA.queryEnvelope2D(envA);
+ Envelope2D envB = new Envelope2D();
+ geometryB.queryEnvelope2D(envB);
+ return envB.distance(envA);
+ }
polygonA = new Polygon();
polygonA.addEnvelope((Envelope) geometryA, false);
- geometryB = polygonA;
+ geometryA = polygonA;
}
// if geom_2 is an envelope use a polygon instead
// if geom_2 is a point use a multipoint instead
- if (geometryB.getType().equals(Geometry.Type.Point)) {
+ if (gtB == Geometry.Type.Point) {
multiPointB = new MultiPoint();
multiPointB.add((Point) geometryB);
geometryB = multiPointB;
- } else if (geometryB.getType().equals(Geometry.Type.Envelope)) {
+ } else if (gtB == Geometry.Type.Envelope) {
polygonB = new Polygon();
polygonB.addEnvelope((Envelope) geometryB, false);
geometryB = polygonB;
@@ -404,7 +425,7 @@ private boolean weakIntersectionTest_(/* const */Geometry geometryA, /* const */
double calculate(/* const */Geometry geometryA, /* const */
Geometry geometryB) {
if (geometryA.isEmpty() || geometryB.isEmpty())
- return 0.0;
+ return NumberUtils.TheNaN;
geometryA.queryEnvelope2D(m_env2DgeometryA);
geometryB.queryEnvelope2D(m_env2DgeometryB);
diff --git a/src/com/esri/core/geometry/OperatorEquals.java b/src/main/java/com/esri/core/geometry/OperatorEquals.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorEquals.java
rename to src/main/java/com/esri/core/geometry/OperatorEquals.java
index 7fb1d5b7..2fb6d3ba 100644
--- a/src/com/esri/core/geometry/OperatorEquals.java
+++ b/src/main/java/com/esri/core/geometry/OperatorEquals.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorEqualsLocal.java b/src/main/java/com/esri/core/geometry/OperatorEqualsLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorEqualsLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorEqualsLocal.java
index d265c55a..d5edf302 100644
--- a/src/com/esri/core/geometry/OperatorEqualsLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorEqualsLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorExportToESRIShape.java b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShape.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorExportToESRIShape.java
rename to src/main/java/com/esri/core/geometry/OperatorExportToESRIShape.java
index 840a1707..56aa754b 100644
--- a/src/com/esri/core/geometry/OperatorExportToESRIShape.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShape.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java
similarity index 99%
rename from src/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java
index f460633a..67d4dfce 100644
--- a/src/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -93,7 +93,7 @@ static int exportToESRIShape(int exportFlags, Geometry geometry,
return exportEnvelopeToESRIShape(exportFlags, (Envelope) geometry,
shapeBuffer);
default: {
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// return -1;
}
}
diff --git a/src/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java
index 9704054e..5b21e632 100644
--- a/src/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/OperatorExportToGeoJson.java b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJson.java
new file mode 100644
index 00000000..6f9d506c
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJson.java
@@ -0,0 +1,80 @@
+/*
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.Operator.Type;
+
+/**
+ *Export to GeoJson format.
+ */
+public abstract class OperatorExportToGeoJson extends Operator {
+ @Override
+ public Type getType() {
+ return Type.ExportToGeoJson;
+ }
+
+ /**
+ * Performs the ExportToGeoJson operation
+ * @param spatialReference The SpatialReference of the Geometry. Will be written as "crs":null if the spatialReference is null.
+ * @param geometryCursor The cursor of geometries to write as GeoJson.
+ * @return Returns a JsonCursor.
+ */
+ public abstract JsonCursor execute(SpatialReference spatialReference, GeometryCursor geometryCursor);
+
+ /**
+ * Performs the ExportToGeoJson operation
+ * @param spatialReference The SpatialReference of the Geometry. Will be written as "crs":null if the spatialReference is null.
+ * @param geometry The Geometry to write as GeoJson.
+ * @return Returns a string in GeoJson format.
+ */
+ public abstract String execute(SpatialReference spatialReference, Geometry geometry);
+
+ /**
+ * Performs the ExportToGeoJson operation
+ * @param exportFlags Use the {@link GeoJsonExportFlags} interface.
+ * @param spatialReference The SpatialReference of the Geometry. Will be written as "crs":null if the spatialReference is null.
+ * @param geometry The Geometry to write as GeoJson.
+ * @return Returns a string in GeoJson format.
+ */
+ public abstract String execute(int exportFlags, SpatialReference spatialReference, Geometry geometry);
+
+ /**
+ * Performs the ExportToGeoJson operation. Will not write out a spatial reference or crs tag. Assumes the geometry is in wgs84.
+ * @param geometry The Geometry to write as GeoJson.
+ * @return Returns a string in GeoJson format.
+ */
+ public abstract String execute(Geometry geometry);
+
+ /**
+ * Performs the ExportToGeoJson operation on a spatial reference.
+ *
+ * @param export_flags The flags used for the export.
+ * @param spatial_reference The spatial reference being exported. Cannot be null.
+ * @return Returns the crs value object.
+ */
+ public abstract String exportSpatialReference(int export_flags, SpatialReference spatial_reference);
+
+ public static OperatorExportToGeoJson local() {
+ return (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance().getOperator(Type.ExportToGeoJson);
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonCursor.java b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonCursor.java
new file mode 100644
index 00000000..0678cef4
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonCursor.java
@@ -0,0 +1,802 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+/*
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.VertexDescription.Semantics;
+
+class OperatorExportToGeoJsonCursor extends JsonCursor {
+ GeometryCursor m_inputGeometryCursor;
+ SpatialReference m_spatialReference;
+ int m_index;
+ int m_export_flags;
+
+ public OperatorExportToGeoJsonCursor(int export_flags, SpatialReference spatialReference,
+ GeometryCursor geometryCursor) {
+ m_index = -1;
+ if (geometryCursor == null)
+ throw new IllegalArgumentException();
+
+ m_export_flags = export_flags;
+ m_spatialReference = spatialReference;
+ m_inputGeometryCursor = geometryCursor;
+ }
+
+ @Override
+ public int getID() {
+ return m_index;
+ }
+
+ @Override
+ public String next() {
+ Geometry geometry;
+ if ((geometry = m_inputGeometryCursor.next()) != null) {
+ m_index = m_inputGeometryCursor.getGeometryID();
+ return exportToGeoJson(m_export_flags, geometry, m_spatialReference);
+ }
+ return null;
+ }
+
+ // Mirrors wkt
+ static String exportToGeoJson(int export_flags, Geometry geometry, SpatialReference spatial_reference) {
+
+ if (geometry == null)
+ throw new IllegalArgumentException("");
+
+ JsonWriter json_writer = new JsonStringWriter();
+
+ json_writer.startObject();
+
+ exportGeometryToGeoJson_(export_flags, geometry, json_writer);
+
+ if ((export_flags & GeoJsonExportFlags.geoJsonExportSkipCRS) == 0) {
+ json_writer.addFieldName("crs");
+ exportSpatialReference(export_flags, spatial_reference, json_writer);
+ }
+
+ json_writer.endObject();
+
+ return (String) json_writer.getJson();
+ }
+
+ static String exportSpatialReference(int export_flags, SpatialReference spatial_reference) {
+ if (spatial_reference == null || (export_flags & GeoJsonExportFlags.geoJsonExportSkipCRS) != 0)
+ throw new IllegalArgumentException("");
+
+ JsonWriter json_writer = new JsonStringWriter();
+ exportSpatialReference(export_flags, spatial_reference, json_writer);
+
+ return (String) json_writer.getJson();
+ }
+
+ private static void exportGeometryToGeoJson_(int export_flags, Geometry geometry, JsonWriter json_writer) {
+ int type = geometry.getType().value();
+ switch (type) {
+ case Geometry.GeometryType.Polygon:
+ exportPolygonToGeoJson_(export_flags, (Polygon) geometry, json_writer);
+ return;
+
+ case Geometry.GeometryType.Polyline:
+ exportPolylineToGeoJson_(export_flags, (Polyline) geometry, json_writer);
+ return;
+
+ case Geometry.GeometryType.MultiPoint:
+ exportMultiPointToGeoJson_(export_flags, (MultiPoint) geometry, json_writer);
+ return;
+
+ case Geometry.GeometryType.Point:
+ exportPointToGeoJson_(export_flags, (Point) geometry, json_writer);
+ return;
+
+ case Geometry.GeometryType.Envelope:
+ exportEnvelopeToGeoJson_(export_flags, (Envelope) geometry,
+ json_writer);
+ return;
+
+ default:
+ throw new RuntimeException("not implemented for this geometry type");
+ }
+ }
+
+ private static void exportSpatialReference(int export_flags, SpatialReference spatial_reference,
+ JsonWriter json_writer) {
+ if (spatial_reference != null) {
+ int wkid = spatial_reference.getLatestID();
+
+ if (wkid <= 0)
+ throw new GeometryException("invalid call");
+
+ json_writer.startObject();
+
+ json_writer.addFieldName("type");
+
+ json_writer.addValueString("name");
+
+ json_writer.addFieldName("properties");
+ json_writer.startObject();
+
+ json_writer.addFieldName("name");
+
+ String authority = ((SpatialReferenceImpl) spatial_reference).getAuthority();
+ authority = authority.toUpperCase();
+ StringBuilder crs_identifier = new StringBuilder(authority);
+ crs_identifier.append(':');
+ crs_identifier.append(wkid);
+ json_writer.addValueString(crs_identifier.toString());
+
+ json_writer.endObject();
+
+ json_writer.endObject();
+ } else {
+ json_writer.addValueNull();
+ }
+ }
+
+ // Mirrors wkt
+ private static void exportPolygonToGeoJson_(int export_flags, Polygon polygon, JsonWriter json_writer) {
+ MultiPathImpl polygon_impl = (MultiPathImpl) (polygon._getImpl());
+
+ if ((export_flags & GeoJsonExportFlags.geoJsonExportFailIfNotSimple) != 0) {
+ int simple = polygon_impl.getIsSimple(0.0);
+
+ if (simple != MultiPathImpl.GeometryXSimple.Strong)
+ throw new GeometryException("corrupted geometry");
+ }
+
+ int point_count = polygon.getPointCount();
+ int polygon_count = polygon_impl.getOGCPolygonCount();
+
+ if (point_count > 0 && polygon_count == 0)
+ throw new GeometryException("corrupted geometry");
+
+ int precision = 17 - (31 & (export_flags >> 13));
+ boolean bFixedPoint = (GeoJsonExportFlags.geoJsonExportPrecisionFixedPoint & export_flags) != 0;
+ boolean b_export_zs = polygon_impl.hasAttribute(VertexDescription.Semantics.Z)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripZs) == 0;
+ boolean b_export_ms = polygon_impl.hasAttribute(VertexDescription.Semantics.M)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripMs) == 0;
+
+ if (!b_export_zs && b_export_ms)
+ throw new IllegalArgumentException("invalid argument");
+
+ int path_count = 0;
+ AttributeStreamOfDbl position = null;
+ AttributeStreamOfDbl zs = null;
+ AttributeStreamOfDbl ms = null;
+ AttributeStreamOfInt8 path_flags = null;
+ AttributeStreamOfInt32 paths = null;
+
+ if (point_count > 0) {
+ position = (AttributeStreamOfDbl) polygon_impl.getAttributeStreamRef(Semantics.POSITION);
+ path_flags = polygon_impl.getPathFlagsStreamRef();
+ paths = polygon_impl.getPathStreamRef();
+ path_count = polygon_impl.getPathCount();
+
+ if (b_export_zs) {
+ if (polygon_impl._attributeStreamIsAllocated(Semantics.Z))
+ zs = (AttributeStreamOfDbl) polygon_impl.getAttributeStreamRef(Semantics.Z);
+ }
+
+ if (b_export_ms) {
+ if (polygon_impl._attributeStreamIsAllocated(Semantics.M))
+ ms = (AttributeStreamOfDbl) polygon_impl.getAttributeStreamRef(Semantics.M);
+ }
+ }
+
+ if ((export_flags & GeoJsonExportFlags.geoJsonExportPreferMultiGeometry) == 0 && polygon_count <= 1)
+ polygonTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, paths, path_count,
+ json_writer);
+ else
+ multiPolygonTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, path_flags,
+ paths, polygon_count, path_count, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void exportPolylineToGeoJson_(int export_flags, Polyline polyline, JsonWriter json_writer) {
+ MultiPathImpl polyline_impl = (MultiPathImpl) polyline._getImpl();
+
+ int point_count = polyline_impl.getPointCount();
+ int path_count = polyline_impl.getPathCount();
+
+ if (point_count > 0 && path_count == 0)
+ throw new GeometryException("corrupted geometry");
+
+ int precision = 17 - (31 & (export_flags >> 13));
+ boolean bFixedPoint = (GeoJsonExportFlags.geoJsonExportPrecisionFixedPoint & export_flags) != 0;
+ boolean b_export_zs = polyline_impl.hasAttribute(VertexDescription.Semantics.Z)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripZs) == 0;
+ boolean b_export_ms = polyline_impl.hasAttribute(VertexDescription.Semantics.M)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripMs) == 0;
+
+ if (!b_export_zs && b_export_ms)
+ throw new IllegalArgumentException("invalid argument");
+
+ AttributeStreamOfDbl position = null;
+ AttributeStreamOfDbl zs = null;
+ AttributeStreamOfDbl ms = null;
+ AttributeStreamOfInt8 path_flags = null;
+ AttributeStreamOfInt32 paths = null;
+
+ if (point_count > 0) {
+ position = (AttributeStreamOfDbl) polyline_impl.getAttributeStreamRef(Semantics.POSITION);
+ path_flags = polyline_impl.getPathFlagsStreamRef();
+ paths = polyline_impl.getPathStreamRef();
+
+ if (b_export_zs) {
+ if (polyline_impl._attributeStreamIsAllocated(Semantics.Z))
+ zs = (AttributeStreamOfDbl) polyline_impl.getAttributeStreamRef(Semantics.Z);
+ }
+
+ if (b_export_ms) {
+ if (polyline_impl._attributeStreamIsAllocated(Semantics.M))
+ ms = (AttributeStreamOfDbl) polyline_impl.getAttributeStreamRef(Semantics.M);
+ }
+ }
+
+ if ((export_flags & GeoJsonExportFlags.geoJsonExportPreferMultiGeometry) == 0 && path_count <= 1)
+ lineStringTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, path_flags, paths,
+ json_writer);
+ else
+ multiLineStringTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, path_flags,
+ paths, path_count, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void exportMultiPointToGeoJson_(int export_flags, MultiPoint multipoint, JsonWriter json_writer) {
+ MultiPointImpl multipoint_impl = (MultiPointImpl) multipoint._getImpl();
+
+ int point_count = multipoint_impl.getPointCount();
+
+ int precision = 17 - (31 & (export_flags >> 13));
+ boolean bFixedPoint = (GeoJsonExportFlags.geoJsonExportPrecisionFixedPoint & export_flags) != 0;
+ boolean b_export_zs = multipoint_impl.hasAttribute(VertexDescription.Semantics.Z)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripZs) == 0;
+ boolean b_export_ms = multipoint_impl.hasAttribute(VertexDescription.Semantics.M)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripMs) == 0;
+
+ if (!b_export_zs && b_export_ms)
+ throw new IllegalArgumentException("invalid argument");
+
+ AttributeStreamOfDbl position = null;
+ AttributeStreamOfDbl zs = null;
+ AttributeStreamOfDbl ms = null;
+
+ if (point_count > 0) {
+ position = (AttributeStreamOfDbl) multipoint_impl.getAttributeStreamRef(Semantics.POSITION);
+
+ if (b_export_zs) {
+ if (multipoint_impl._attributeStreamIsAllocated(Semantics.Z))
+ zs = (AttributeStreamOfDbl) multipoint_impl.getAttributeStreamRef(Semantics.Z);
+ }
+
+ if (b_export_ms) {
+ if (multipoint_impl._attributeStreamIsAllocated(Semantics.M))
+ ms = (AttributeStreamOfDbl) multipoint_impl.getAttributeStreamRef(Semantics.M);
+ }
+ }
+
+ multiPointTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, point_count,
+ json_writer);
+ }
+
+ // Mirrors wkt
+ private static void exportPointToGeoJson_(int export_flags, Point point, JsonWriter json_writer) {
+ int precision = 17 - (31 & (export_flags >> 13));
+ boolean bFixedPoint = (GeoJsonExportFlags.geoJsonExportPrecisionFixedPoint & export_flags) != 0;
+ boolean b_export_zs = point.hasAttribute(VertexDescription.Semantics.Z)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripZs) == 0;
+ boolean b_export_ms = point.hasAttribute(VertexDescription.Semantics.M)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripMs) == 0;
+
+ if (!b_export_zs && b_export_ms)
+ throw new IllegalArgumentException("invalid argument");
+
+ double x = NumberUtils.NaN();
+ double y = NumberUtils.NaN();
+ double z = NumberUtils.NaN();
+ double m = NumberUtils.NaN();
+
+ if (!point.isEmpty()) {
+ x = point.getX();
+ y = point.getY();
+
+ if (b_export_zs)
+ z = point.getZ();
+
+ if (b_export_ms)
+ m = point.getM();
+ }
+
+ if ((export_flags & GeoJsonExportFlags.geoJsonExportPreferMultiGeometry) == 0)
+ pointTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, x, y, z, m, json_writer);
+ else
+ multiPointTaggedTextFromPoint_(precision, bFixedPoint, b_export_zs, b_export_ms, x, y, z, m, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void exportEnvelopeToGeoJson_(int export_flags, Envelope envelope, JsonWriter json_writer) {
+ int precision = 17 - (31 & (export_flags >> 13));
+ boolean bFixedPoint = (GeoJsonExportFlags.geoJsonExportPrecisionFixedPoint & export_flags) != 0;
+ boolean b_export_zs = envelope.hasAttribute(VertexDescription.Semantics.Z)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripZs) == 0;
+ boolean b_export_ms = envelope.hasAttribute(VertexDescription.Semantics.M)
+ && (export_flags & GeoJsonExportFlags.geoJsonExportStripMs) == 0;
+
+ if (!b_export_zs && b_export_ms)
+ throw new IllegalArgumentException("invalid argument");
+
+ double xmin = NumberUtils.NaN();
+ double ymin = NumberUtils.NaN();
+ double xmax = NumberUtils.NaN();
+ double ymax = NumberUtils.NaN();
+ double zmin = NumberUtils.NaN();
+ double zmax = NumberUtils.NaN();
+ double mmin = NumberUtils.NaN();
+ double mmax = NumberUtils.NaN();
+
+ if (!envelope.isEmpty()) {
+ xmin = envelope.getXMin();
+ ymin = envelope.getYMin();
+ xmax = envelope.getXMax();
+ ymax = envelope.getYMax();
+
+ Envelope1D interval;
+
+ if (b_export_zs) {
+ interval = envelope.queryInterval(Semantics.Z, 0);
+ zmin = interval.vmin;
+ zmax = interval.vmax;
+ }
+
+ if (b_export_ms) {
+ interval = envelope.queryInterval(Semantics.M, 0);
+ mmin = interval.vmin;
+ mmax = interval.vmax;
+ }
+ }
+
+ if ((export_flags & GeoJsonExportFlags.geoJsonExportPreferMultiGeometry) == 0)
+ polygonTaggedTextFromEnvelope_(precision, bFixedPoint, b_export_zs, b_export_ms, xmin, ymin, xmax, ymax,
+ zmin, zmax, mmin, mmax, json_writer);
+ else
+ multiPolygonTaggedTextFromEnvelope_(precision, bFixedPoint, b_export_zs, b_export_ms, xmin, ymin, xmax,
+ ymax, zmin, zmax, mmin, mmax, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void multiPolygonTaggedText_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ AttributeStreamOfInt8 path_flags, AttributeStreamOfInt32 paths, int polygon_count, int path_count,
+ JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("MultiPolygon");
+
+ json_writer.addFieldName("coordinates");
+
+ if (position == null) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ json_writer.startArray();
+
+ multiPolygonText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, path_flags, paths,
+ polygon_count, path_count, json_writer);
+
+ json_writer.endArray();
+ }
+
+ // Mirrors wkt
+ private static void multiPolygonTaggedTextFromEnvelope_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, double xmin, double ymin, double xmax, double ymax, double zmin, double zmax,
+ double mmin, double mmax, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("MultiPolygon");
+
+ json_writer.addFieldName("coordinates");
+
+ if (NumberUtils.isNaN(xmin)) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ json_writer.startArray();
+
+ writeEnvelopeAsGeoJsonPolygon_(precision, bFixedPoint, b_export_zs, b_export_ms, xmin, ymin, xmax, ymax, zmin,
+ zmax, mmin, mmax, json_writer);
+
+ json_writer.endArray();
+ }
+
+ // Mirrors wkt
+ private static void multiLineStringTaggedText_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ AttributeStreamOfInt8 path_flags, AttributeStreamOfInt32 paths, int path_count, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("MultiLineString");
+
+ json_writer.addFieldName("coordinates");
+
+ if (position == null) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ json_writer.startArray();
+
+ multiLineStringText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, path_flags, paths,
+ path_count, json_writer);
+
+ json_writer.endArray();
+ }
+
+ // Mirrors wkt
+ private static void multiPointTaggedText_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ int point_count, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("MultiPoint");
+
+ json_writer.addFieldName("coordinates");
+
+ if (position == null) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ lineStringText_(false, false, precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, 0,
+ point_count, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void multiPointTaggedTextFromPoint_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, double x, double y, double z, double m, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("MultiPoint");
+
+ json_writer.addFieldName("coordinates");
+
+ if (NumberUtils.isNaN(x)) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ json_writer.startArray();
+
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, x, y, z, m, json_writer);
+
+ json_writer.endArray();
+ }
+
+ // Mirrors wkt
+ private static void polygonTaggedText_(int precision, boolean bFixedPoint, boolean b_export_zs, boolean b_export_ms,
+ AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ AttributeStreamOfInt32 paths, int path_count, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("Polygon");
+
+ json_writer.addFieldName("coordinates");
+
+ if (position == null) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ polygonText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, paths, 0, path_count,
+ json_writer);
+ }
+
+ // Mirrors wkt
+ private static void polygonTaggedTextFromEnvelope_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, double xmin, double ymin, double xmax, double ymax, double zmin, double zmax,
+ double mmin, double mmax, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("Polygon");
+
+ json_writer.addFieldName("coordinates");
+
+ if (NumberUtils.isNaN(xmin)) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ writeEnvelopeAsGeoJsonPolygon_(precision, bFixedPoint, b_export_zs, b_export_ms, xmin, ymin, xmax, ymax, zmin,
+ zmax, mmin, mmax, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void lineStringTaggedText_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ AttributeStreamOfInt8 path_flags, AttributeStreamOfInt32 paths, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("LineString");
+
+ json_writer.addFieldName("coordinates");
+
+ if (position == null) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ boolean b_closed = ((path_flags.read(0) & PathFlags.enumClosed) != 0);
+
+ lineStringText_(false, b_closed, precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, 0,
+ paths.read(1), json_writer);
+ }
+
+ // Mirrors wkt
+ private static void pointTaggedText_(int precision, boolean bFixedPoint, boolean b_export_zs, boolean b_export_ms,
+ double x, double y, double z, double m, JsonWriter json_writer) {
+ json_writer.addFieldName("type");
+ json_writer.addValueString("Point");
+
+ json_writer.addFieldName("coordinates");
+
+ if (NumberUtils.isNaN(x)) {
+ json_writer.startArray();
+ json_writer.endArray();
+
+ return;
+ }
+
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, x, y, z, m, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void multiPolygonText_(int precision, boolean bFixedPoint, boolean b_export_zs, boolean b_export_ms,
+ AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ AttributeStreamOfInt8 path_flags, AttributeStreamOfInt32 paths, int polygon_count, int path_count,
+ JsonWriter json_writer) {
+ int polygon_start = 0;
+ int polygon_end = 1;
+
+ while (polygon_end < path_count && ((int) path_flags.read(polygon_end) & PathFlags.enumOGCStartPolygon) == 0)
+ polygon_end++;
+
+ polygonText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, paths, polygon_start,
+ polygon_end, json_writer);
+
+ for (int ipolygon = 1; ipolygon < polygon_count; ipolygon++) {
+ polygon_start = polygon_end;
+ polygon_end++;
+
+ while (polygon_end < path_count
+ && ((int) path_flags.read(polygon_end) & PathFlags.enumOGCStartPolygon) == 0)
+ polygon_end++;
+
+ polygonText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, paths, polygon_start,
+ polygon_end, json_writer);
+ }
+ }
+
+ // Mirrors wkt
+ private static void multiLineStringText_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ AttributeStreamOfInt8 path_flags, AttributeStreamOfInt32 paths, int path_count, JsonWriter json_writer) {
+ boolean b_closed = ((path_flags.read(0) & PathFlags.enumClosed) != 0);
+
+ lineStringText_(false, b_closed, precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, 0,
+ paths.read(1), json_writer);
+
+ for (int path = 1; path < path_count; path++) {
+ b_closed = ((path_flags.read(path) & PathFlags.enumClosed) != 0);
+
+ int istart = paths.read(path);
+ int iend = paths.read(path + 1);
+ lineStringText_(false, b_closed, precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, istart,
+ iend, json_writer);
+ }
+ }
+
+ // Mirrors wkt
+ private static void polygonText_(int precision, boolean bFixedPoint, boolean b_export_zs, boolean b_export_ms,
+ AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
+ AttributeStreamOfInt32 paths, int polygon_start, int polygon_end, JsonWriter json_writer) {
+ json_writer.startArray();
+
+ int istart = paths.read(polygon_start);
+ int iend = paths.read(polygon_start + 1);
+ lineStringText_(true, true, precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, istart, iend,
+ json_writer);
+
+ for (int path = polygon_start + 1; path < polygon_end; path++) {
+ istart = paths.read(path);
+ iend = paths.read(path + 1);
+ lineStringText_(true, true, precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, istart,
+ iend, json_writer);
+ }
+
+ json_writer.endArray();
+ }
+
+ // Mirrors wkt
+ private static void lineStringText_(boolean bRing, boolean b_closed, int precision, boolean bFixedPoint,
+ boolean b_export_zs, boolean b_export_ms, AttributeStreamOfDbl zs, AttributeStreamOfDbl ms,
+ AttributeStreamOfDbl position, int istart, int iend, JsonWriter json_writer) {
+ if (istart == iend) {
+ json_writer.startArray();
+ json_writer.endArray();
+ return;
+ }
+
+ json_writer.startArray();
+
+ if (bRing) {
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, istart, json_writer);
+
+ for (int point = iend - 1; point >= istart + 1; point--)
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, point, json_writer);
+
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, istart, json_writer);
+ } else {
+ for (int point = istart; point < iend - 1; point++)
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, point, json_writer);
+
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, iend - 1, json_writer);
+
+ if (b_closed)
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, istart, json_writer);
+ }
+
+ json_writer.endArray();
+ }
+
+ // Mirrors wkt
+ private static int pointText_(int precision, boolean bFixedPoint, boolean b_export_zs, boolean b_export_ms,
+ double x, double y, double z, double m, JsonWriter json_writer) {
+
+ json_writer.startArray();
+
+ json_writer.addValueDouble(x, precision, bFixedPoint);
+ json_writer.addValueDouble(y, precision, bFixedPoint);
+
+ if (b_export_zs)
+ json_writer.addValueDouble(z, precision, bFixedPoint);
+
+ if (b_export_ms)
+ json_writer.addValueDouble(m, precision, bFixedPoint);
+
+ json_writer.endArray();
+
+ return 1;
+ }
+
+ // Mirrors wkt
+ private static void pointText_(int precision, boolean bFixedPoint, boolean b_export_zs, boolean b_export_ms,
+ AttributeStreamOfDbl zs, AttributeStreamOfDbl ms, AttributeStreamOfDbl position, int point,
+ JsonWriter json_writer) {
+ double x = position.readAsDbl(2 * point);
+ double y = position.readAsDbl(2 * point + 1);
+ double z = NumberUtils.NaN();
+ double m = NumberUtils.NaN();
+
+ if (b_export_zs)
+ z = (zs != null ? zs.readAsDbl(point) : VertexDescription.getDefaultValue(Semantics.Z));
+
+ if (b_export_ms)
+ m = (ms != null ? ms.readAsDbl(point) : VertexDescription.getDefaultValue(Semantics.M));
+
+ pointText_(precision, bFixedPoint, b_export_zs, b_export_ms, x, y, z, m, json_writer);
+ }
+
+ // Mirrors wkt
+ private static void writeEnvelopeAsGeoJsonPolygon_(int precision, boolean bFixedPoint, boolean b_export_zs,
+ boolean b_export_ms, double xmin, double ymin, double xmax, double ymax, double zmin, double zmax,
+ double mmin, double mmax, JsonWriter json_writer) {
+ json_writer.startArray();
+ json_writer.startArray();
+
+ json_writer.startArray();
+ json_writer.addValueDouble(xmin, precision, bFixedPoint);
+ json_writer.addValueDouble(ymin, precision, bFixedPoint);
+
+ if (b_export_zs)
+ json_writer.addValueDouble(zmin, precision, bFixedPoint);
+
+ if (b_export_ms)
+ json_writer.addValueDouble(mmin, precision, bFixedPoint);
+
+ json_writer.endArray();
+
+ json_writer.startArray();
+ json_writer.addValueDouble(xmax, precision, bFixedPoint);
+ json_writer.addValueDouble(ymin, precision, bFixedPoint);
+
+ if (b_export_zs)
+ json_writer.addValueDouble(zmax, precision, bFixedPoint);
+
+ if (b_export_ms)
+ json_writer.addValueDouble(mmax, precision, bFixedPoint);
+
+ json_writer.endArray();
+
+ json_writer.startArray();
+ json_writer.addValueDouble(xmax, precision, bFixedPoint);
+ json_writer.addValueDouble(ymax, precision, bFixedPoint);
+
+ if (b_export_zs)
+ json_writer.addValueDouble(zmin, precision, bFixedPoint);
+
+ if (b_export_ms)
+ json_writer.addValueDouble(mmin, precision, bFixedPoint);
+
+ json_writer.endArray();
+
+ json_writer.startArray();
+ json_writer.addValueDouble(xmin, precision, bFixedPoint);
+ json_writer.addValueDouble(ymax, precision, bFixedPoint);
+
+ if (b_export_zs)
+ json_writer.addValueDouble(zmax, precision, bFixedPoint);
+
+ if (b_export_ms)
+ json_writer.addValueDouble(mmax, precision, bFixedPoint);
+
+ json_writer.endArray();
+
+ json_writer.startArray();
+ json_writer.addValueDouble(xmin, precision, bFixedPoint);
+ json_writer.addValueDouble(ymin, precision, bFixedPoint);
+
+ if (b_export_zs)
+ json_writer.addValueDouble(zmin, precision, bFixedPoint);
+
+ if (b_export_ms)
+ json_writer.addValueDouble(mmin, precision, bFixedPoint);
+
+ json_writer.endArray();
+
+ json_writer.endArray();
+ json_writer.endArray();
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonLocal.java
new file mode 100644
index 00000000..9da02767
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonLocal.java
@@ -0,0 +1,50 @@
+/*
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+class OperatorExportToGeoJsonLocal extends OperatorExportToGeoJson {
+ @Override
+ public JsonCursor execute(SpatialReference spatialReference, GeometryCursor geometryCursor) {
+ return new OperatorExportToGeoJsonCursor(GeoJsonExportFlags.geoJsonExportDefaults, spatialReference, geometryCursor);
+ }
+
+ @Override
+ public String execute(SpatialReference spatialReference, Geometry geometry) {
+ return OperatorExportToGeoJsonCursor.exportToGeoJson(GeoJsonExportFlags.geoJsonExportDefaults, geometry, spatialReference);
+ }
+
+ @Override
+ public String execute(int exportFlags, SpatialReference spatialReference, Geometry geometry) {
+ return OperatorExportToGeoJsonCursor.exportToGeoJson(exportFlags, geometry, spatialReference);
+ }
+
+ @Override
+ public String execute(Geometry geometry) {
+ return OperatorExportToGeoJsonCursor.exportToGeoJson(GeoJsonExportFlags.geoJsonExportSkipCRS, geometry, null);
+ }
+
+ @Override
+ public String exportSpatialReference(int export_flags, SpatialReference spatial_reference) {
+ return OperatorExportToGeoJsonCursor.exportSpatialReference(export_flags, spatial_reference);
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorExportToJson.java b/src/main/java/com/esri/core/geometry/OperatorExportToJson.java
new file mode 100644
index 00000000..32bfc078
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToJson.java
@@ -0,0 +1,68 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.util.Map;
+
+import com.esri.core.geometry.Operator.Type;
+
+/**
+ * Export to JSON format.
+ */
+public abstract class OperatorExportToJson extends Operator {
+
+ @Override
+ public Type getType() {
+ return Type.ExportToJson;
+ }
+
+ /**
+ * Performs the ExportToJson operation
+ *
+ * @return Returns a JsonCursor.
+ */
+ public abstract JsonCursor execute(SpatialReference spatialReference,
+ GeometryCursor geometryCursor);
+
+ /**
+ * Performs the ExportToJson operation
+ *
+ * @return Returns a String.
+ */
+ public abstract String execute(SpatialReference spatialReference,
+ Geometry geometry);
+
+ /**
+ * Performs the ExportToJson operation
+ *
+ * @return Returns a String.
+ */
+ public abstract String execute(SpatialReference spatialReference,
+ Geometry geometry, Map exportProperties);
+
+ public static OperatorExportToJson local() {
+ return (OperatorExportToJson) OperatorFactoryLocal.getInstance()
+ .getOperator(Type.ExportToJson);
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorExportToJsonCursor.java b/src/main/java/com/esri/core/geometry/OperatorExportToJsonCursor.java
new file mode 100644
index 00000000..9d24be43
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToJsonCursor.java
@@ -0,0 +1,459 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.VertexDescription.Semantics;
+
+import java.io.IOException;
+import java.util.Map;
+
+class OperatorExportToJsonCursor extends JsonCursor {
+
+ GeometryCursor m_inputGeometryCursor;
+ SpatialReference m_spatialReference;
+ int m_index;
+
+ public OperatorExportToJsonCursor(SpatialReference spatialReference, GeometryCursor geometryCursor) {
+ m_index = -1;
+ if (geometryCursor == null) {
+ throw new IllegalArgumentException();
+ }
+
+ m_inputGeometryCursor = geometryCursor;
+ m_spatialReference = spatialReference;
+ }
+
+ @Override
+ public int getID() {
+ return m_index;
+ }
+
+ @Override
+ public String next() {
+ Geometry geometry;
+ if ((geometry = m_inputGeometryCursor.next()) != null) {
+ m_index = m_inputGeometryCursor.getGeometryID();
+ return exportToString(geometry, m_spatialReference, null);
+ }
+ return null;
+ }
+
+ static String exportToString(Geometry geometry, SpatialReference spatialReference, Map exportProperties) {
+ JsonWriter jsonWriter = new JsonStringWriter();
+ exportToJson_(geometry, spatialReference, jsonWriter, exportProperties);
+ return (String) jsonWriter.getJson();
+ }
+
+ private static void exportToJson_(Geometry geometry, SpatialReference spatialReference, JsonWriter jsonWriter, Map exportProperties) {
+ try {
+ int type = geometry.getType().value();
+ switch (type) {
+ case Geometry.GeometryType.Point:
+ exportPointToJson((Point) geometry, spatialReference, jsonWriter, exportProperties);
+ break;
+
+ case Geometry.GeometryType.MultiPoint:
+ exportMultiPointToJson((MultiPoint) geometry, spatialReference, jsonWriter, exportProperties);
+ break;
+
+ case Geometry.GeometryType.Polyline:
+ exportPolylineToJson((Polyline) geometry, spatialReference, jsonWriter, exportProperties);
+ break;
+
+ case Geometry.GeometryType.Polygon:
+ exportPolygonToJson((Polygon) geometry, spatialReference, jsonWriter, exportProperties);
+ break;
+
+ case Geometry.GeometryType.Envelope:
+ exportEnvelopeToJson((Envelope) geometry, spatialReference, jsonWriter, exportProperties);
+ break;
+
+ default:
+ throw new RuntimeException("not implemented for this geometry type");
+ }
+
+ } catch (Exception e) {
+ }
+
+ }
+
+ private static void exportPolygonToJson(Polygon pp, SpatialReference spatialReference, JsonWriter jsonWriter, Map exportProperties) {
+ exportPolypathToJson(pp, "rings", spatialReference, jsonWriter, exportProperties);
+ }
+
+ private static void exportPolylineToJson(Polyline pp, SpatialReference spatialReference, JsonWriter jsonWriter, Map exportProperties) {
+ exportPolypathToJson(pp, "paths", spatialReference, jsonWriter, exportProperties);
+ }
+
+ private static void exportPolypathToJson(MultiPath pp, String name, SpatialReference spatialReference, JsonWriter jsonWriter, Map exportProperties) {
+ boolean bExportZs = pp.hasAttribute(Semantics.Z);
+ boolean bExportMs = pp.hasAttribute(Semantics.M);
+
+ boolean bPositionAsF = false;
+ int decimals = 17;
+
+ if (exportProperties != null) {
+ Object numberOfDecimalsXY = exportProperties.get("numberOfDecimalsXY");
+ if (numberOfDecimalsXY != null && numberOfDecimalsXY instanceof Number) {
+ bPositionAsF = true;
+ decimals = ((Number) numberOfDecimalsXY).intValue();
+ }
+ }
+
+ jsonWriter.startObject();
+
+ if (bExportZs) {
+ jsonWriter.addPairBoolean("hasZ", true);
+ }
+
+ if (bExportMs) {
+ jsonWriter.addPairBoolean("hasM", true);
+ }
+
+ jsonWriter.addPairArray(name);
+
+ if (!pp.isEmpty()) {
+ int n = pp.getPathCount(); // rings or paths
+
+ MultiPathImpl mpImpl = (MultiPathImpl) pp._getImpl();// get impl for
+ // faster
+ // access
+ AttributeStreamOfDbl zs = null;
+ AttributeStreamOfDbl ms = null;
+
+ if (bExportZs) {
+ zs = (AttributeStreamOfDbl) mpImpl.getAttributeStreamRef(Semantics.Z);
+ }
+
+ if (bExportMs) {
+ ms = (AttributeStreamOfDbl) mpImpl.getAttributeStreamRef(Semantics.M);
+ }
+
+ boolean bPolygon = pp instanceof Polygon;
+ Point2D pt = new Point2D();
+
+ for (int i = 0; i < n; i++) {
+ jsonWriter.addValueArray();
+ int startindex = pp.getPathStart(i);
+ int numVertices = pp.getPathSize(i);
+ double startx = 0.0, starty = 0.0, startz = NumberUtils.NaN(), startm = NumberUtils.NaN();
+ double z = NumberUtils.NaN(), m = NumberUtils.NaN();
+ boolean bClosed = pp.isClosedPath(i);
+ for (int j = startindex; j < startindex + numVertices; j++) {
+ pp.getXY(j, pt);
+
+ jsonWriter.addValueArray();
+
+ if (bPositionAsF) {
+ jsonWriter.addValueDouble(pt.x, decimals, true);
+ jsonWriter.addValueDouble(pt.y, decimals, true);
+ } else {
+ jsonWriter.addValueDouble(pt.x);
+ jsonWriter.addValueDouble(pt.y);
+ }
+
+ if (bExportZs) {
+ z = zs.get(j);
+ jsonWriter.addValueDouble(z);
+ }
+
+ if (bExportMs) {
+ m = ms.get(j);
+ jsonWriter.addValueDouble(m);
+ }
+
+ if (j == startindex && bClosed) {
+ startx = pt.x;
+ starty = pt.y;
+ startz = z;
+ startm = m;
+ }
+
+ jsonWriter.endArray();
+ }
+
+ // Close the Path/Ring by writing the Point at the start index
+ if (bClosed && (startx != pt.x || starty != pt.y || (bExportZs && !(NumberUtils.isNaN(startz) && NumberUtils.isNaN(z)) && startz != z) || (bExportMs && !(NumberUtils.isNaN(startm) && NumberUtils.isNaN(m)) && startm != m))) {
+ pp.getXY(startindex, pt);
+ // getPoint(startindex);
+ jsonWriter.addValueArray();
+
+ if (bPositionAsF) {
+ jsonWriter.addValueDouble(pt.x, decimals, true);
+ jsonWriter.addValueDouble(pt.y, decimals, true);
+ } else {
+ jsonWriter.addValueDouble(pt.x);
+ jsonWriter.addValueDouble(pt.y);
+ }
+
+ if (bExportZs) {
+ z = zs.get(startindex);
+ jsonWriter.addValueDouble(z);
+ }
+
+ if (bExportMs) {
+ m = ms.get(startindex);
+ jsonWriter.addValueDouble(m);
+ }
+
+ jsonWriter.endArray();
+ }
+
+ jsonWriter.endArray();
+ }
+ }
+
+ jsonWriter.endArray();
+
+ if (spatialReference != null) {
+ writeSR(spatialReference, jsonWriter);
+ }
+
+ jsonWriter.endObject();
+ }
+
+ private static void exportMultiPointToJson(MultiPoint mpt, SpatialReference spatialReference, JsonWriter jsonWriter, Map exportProperties) {
+ boolean bExportZs = mpt.hasAttribute(Semantics.Z);
+ boolean bExportMs = mpt.hasAttribute(Semantics.M);
+
+ boolean bPositionAsF = false;
+ int decimals = 17;
+
+ if (exportProperties != null) {
+ Object numberOfDecimalsXY = exportProperties.get("numberOfDecimalsXY");
+ if (numberOfDecimalsXY != null && numberOfDecimalsXY instanceof Number) {
+ bPositionAsF = true;
+ decimals = ((Number) numberOfDecimalsXY).intValue();
+ }
+ }
+
+ jsonWriter.startObject();
+
+ if (bExportZs) {
+ jsonWriter.addPairBoolean("hasZ", true);
+ }
+
+ if (bExportMs) {
+ jsonWriter.addPairBoolean("hasM", true);
+ }
+
+ jsonWriter.addPairArray("points");
+
+ if (!mpt.isEmpty()) {
+ MultiPointImpl mpImpl = (MultiPointImpl) mpt._getImpl();// get impl
+ // for
+ // faster
+ // access
+ AttributeStreamOfDbl zs = null;
+ AttributeStreamOfDbl ms = null;
+
+ if (bExportZs) {
+ zs = (AttributeStreamOfDbl) mpImpl.getAttributeStreamRef(Semantics.Z);
+ }
+
+ if (bExportMs) {
+ ms = (AttributeStreamOfDbl) mpImpl.getAttributeStreamRef(Semantics.M);
+ }
+
+ Point2D pt = new Point2D();
+ int n = mpt.getPointCount();
+ for (int i = 0; i < n; i++) {
+ mpt.getXY(i, pt);
+
+ jsonWriter.addValueArray();
+
+ if (bPositionAsF) {
+ jsonWriter.addValueDouble(pt.x, decimals, true);
+ jsonWriter.addValueDouble(pt.y, decimals, true);
+ } else {
+ jsonWriter.addValueDouble(pt.x);
+ jsonWriter.addValueDouble(pt.y);
+ }
+
+ if (bExportZs) {
+ double z = zs.get(i);
+ jsonWriter.addValueDouble(z);
+ }
+
+ if (bExportMs) {
+ double m = ms.get(i);
+ jsonWriter.addValueDouble(m);
+ }
+
+ jsonWriter.endArray();
+ }
+ }
+
+ jsonWriter.endArray();
+
+ if (spatialReference != null) {
+ writeSR(spatialReference, jsonWriter);
+ }
+
+ jsonWriter.endObject();
+ }
+
+ private static void exportPointToJson(Point pt, SpatialReference spatialReference, JsonWriter jsonWriter, Map exportProperties) {
+ boolean bExportZs = pt.hasAttribute(Semantics.Z);
+ boolean bExportMs = pt.hasAttribute(Semantics.M);
+
+ boolean bPositionAsF = false;
+ int decimals = 17;
+
+ if (exportProperties != null) {
+ Object numberOfDecimalsXY = exportProperties.get("numberOfDecimalsXY");
+ if (numberOfDecimalsXY != null && numberOfDecimalsXY instanceof Number) {
+ bPositionAsF = true;
+ decimals = ((Number) numberOfDecimalsXY).intValue();
+ }
+ }
+
+ jsonWriter.startObject();
+
+ if (pt.isEmpty()) {
+ jsonWriter.addPairNull("x");
+ jsonWriter.addPairNull("y");
+
+ if (bExportZs) {
+ jsonWriter.addPairNull("z");
+ }
+
+ if (bExportMs) {
+ jsonWriter.addPairNull("m");
+ }
+ } else {
+
+ if (bPositionAsF) {
+ jsonWriter.addPairDouble("x", pt.getX(), decimals, true);
+ jsonWriter.addPairDouble("y", pt.getY(), decimals, true);
+ } else {
+ jsonWriter.addPairDouble("x", pt.getX());
+ jsonWriter.addPairDouble("y", pt.getY());
+ }
+
+ if (bExportZs) {
+ jsonWriter.addPairDouble("z", pt.getZ());
+ }
+
+ if (bExportMs) {
+ jsonWriter.addPairDouble("m", pt.getM());
+ }
+ }
+
+ if (spatialReference != null) {
+ writeSR(spatialReference, jsonWriter);
+ }
+
+ jsonWriter.endObject();
+ }
+
+ private static void exportEnvelopeToJson(Envelope env, SpatialReference spatialReference, JsonWriter jsonWriter, Map exportProperties) {
+ boolean bExportZs = env.hasAttribute(Semantics.Z);
+ boolean bExportMs = env.hasAttribute(Semantics.M);
+
+ boolean bPositionAsF = false;
+ int decimals = 17;
+
+ if (exportProperties != null) {
+ Object numberOfDecimalsXY = exportProperties.get("numberOfDecimalsXY");
+ if (numberOfDecimalsXY != null && numberOfDecimalsXY instanceof Number) {
+ bPositionAsF = true;
+ decimals = ((Number) numberOfDecimalsXY).intValue();
+ }
+ }
+
+ jsonWriter.startObject();
+
+ if (env.isEmpty()) {
+ jsonWriter.addPairNull("xmin");
+ jsonWriter.addPairNull("ymin");
+ jsonWriter.addPairNull("xmax");
+ jsonWriter.addPairNull("ymax");
+
+ if (bExportZs) {
+ jsonWriter.addPairNull("zmin");
+ jsonWriter.addPairNull("zmax");
+ }
+
+ if (bExportMs) {
+ jsonWriter.addPairNull("mmin");
+ jsonWriter.addPairNull("mmax");
+ }
+ } else {
+
+ if (bPositionAsF) {
+ jsonWriter.addPairDouble("xmin", env.getXMin(), decimals, true);
+ jsonWriter.addPairDouble("ymin", env.getYMin(), decimals, true);
+ jsonWriter.addPairDouble("xmax", env.getXMax(), decimals, true);
+ jsonWriter.addPairDouble("ymax", env.getYMax(), decimals, true);
+ } else {
+ jsonWriter.addPairDouble("xmin", env.getXMin());
+ jsonWriter.addPairDouble("ymin", env.getYMin());
+ jsonWriter.addPairDouble("xmax", env.getXMax());
+ jsonWriter.addPairDouble("ymax", env.getYMax());
+ }
+
+ if (bExportZs) {
+ Envelope1D z = env.queryInterval(Semantics.Z, 0);
+ jsonWriter.addPairDouble("zmin", z.vmin);
+ jsonWriter.addPairDouble("zmax", z.vmax);
+ }
+
+ if (bExportMs) {
+ Envelope1D m = env.queryInterval(Semantics.M, 0);
+ jsonWriter.addPairDouble("mmin", m.vmin);
+ jsonWriter.addPairDouble("mmax", m.vmax);
+ }
+ }
+
+ if (spatialReference != null) {
+ writeSR(spatialReference, jsonWriter);
+ }
+
+ jsonWriter.endObject();
+ }
+
+ private static void writeSR(SpatialReference spatialReference, JsonWriter jsonWriter) {
+ int wkid = spatialReference.getOldID();
+ if (wkid > 0) {
+ jsonWriter.addPairObject("spatialReference");
+
+ jsonWriter.addPairInt("wkid", wkid);
+
+ int latest_wkid = spatialReference.getLatestID();
+ if (latest_wkid > 0 && latest_wkid != wkid) {
+ jsonWriter.addPairInt("latestWkid", latest_wkid);
+ }
+
+ jsonWriter.endObject();
+ } else {
+ String wkt = spatialReference.getText();
+ if (wkt != null) {
+ jsonWriter.addPairObject("spatialReference");
+ jsonWriter.addPairString("wkt", wkt);
+ jsonWriter.endObject();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorExportToJsonLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToJsonLocal.java
new file mode 100644
index 00000000..65554574
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToJsonLocal.java
@@ -0,0 +1,48 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.util.Map;
+
+class OperatorExportToJsonLocal extends OperatorExportToJson {
+
+ @Override
+ public JsonCursor execute(SpatialReference spatialReference,
+ GeometryCursor geometryCursor) {
+ return new OperatorExportToJsonCursor(spatialReference, geometryCursor);
+ }
+
+ @Override
+ public String execute(SpatialReference spatialReference, Geometry geometry) {
+ SimpleGeometryCursor gc = new SimpleGeometryCursor(geometry);
+ JsonCursor cursor = new OperatorExportToJsonCursor(spatialReference, gc);
+ return cursor.next();
+ }
+
+ @Override
+ public String execute(SpatialReference spatialReference,
+ Geometry geometry, Map exportProperties) {
+ return OperatorExportToJsonCursor.exportToString(geometry, spatialReference, exportProperties);
+ }
+}
diff --git a/src/com/esri/core/geometry/OperatorExportToWkb.java b/src/main/java/com/esri/core/geometry/OperatorExportToWkb.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorExportToWkb.java
rename to src/main/java/com/esri/core/geometry/OperatorExportToWkb.java
index d4418b2c..fba948cb 100644
--- a/src/com/esri/core/geometry/OperatorExportToWkb.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToWkb.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorExportToWkbLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToWkbLocal.java
similarity index 99%
rename from src/com/esri/core/geometry/OperatorExportToWkbLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorExportToWkbLocal.java
index 3b4fedfe..a1ddec68 100644
--- a/src/com/esri/core/geometry/OperatorExportToWkbLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToWkbLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -97,7 +97,7 @@ private static int exportToWKB(int exportFlags, Geometry geometry,
wkbBuffer);
default: {
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// return -1;
}
}
@@ -170,7 +170,7 @@ else if (wkbBuffer.capacity() < size)
if (!bExportZs && !bExportMs) {
type = WkbGeometryType.wkbPolygon;
- if ((exportFlags & WktExportFlags.wktExportPolygon) == 0) {
+ if ((exportFlags & WkbExportFlags.wkbExportPolygon) == 0) {
wkbBuffer.put(offset, byteOrder);
offset += 1;
wkbBuffer.putInt(offset, WkbGeometryType.wkbMultiPolygon);
@@ -750,7 +750,7 @@ else if (wkbBuffer.capacity() < (int) size)
if ((exportFlags & WkbExportFlags.wkbExportPoint) == 0) {
wkbBuffer.put(offset, byteOrder);
offset += 1;
- wkbBuffer.putInt(offset, WkbGeometryType.wkbMultiPolygonZM);
+ wkbBuffer.putInt(offset, WkbGeometryType.wkbMultiPointZM);
offset += 4;
wkbBuffer.putInt(offset, point_count);
offset += 4;
diff --git a/src/com/esri/core/geometry/OperatorExportToWkt.java b/src/main/java/com/esri/core/geometry/OperatorExportToWkt.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorExportToWkt.java
rename to src/main/java/com/esri/core/geometry/OperatorExportToWkt.java
index 6e893b14..10eab9b2 100644
--- a/src/com/esri/core/geometry/OperatorExportToWkt.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToWkt.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorExportToWktLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToWktLocal.java
similarity index 96%
rename from src/com/esri/core/geometry/OperatorExportToWktLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorExportToWktLocal.java
index cdcefd84..0b3a4466 100644
--- a/src/com/esri/core/geometry/OperatorExportToWktLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToWktLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ static void exportToWkt(int export_flags, Geometry geometry,
|| (export_flags & WktExportFlags.wktExportMultiLineString) != 0
|| (export_flags & WktExportFlags.wktExportPoint) != 0
|| (export_flags & WktExportFlags.wktExportMultiPoint) != 0)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export a Polygon as (Multi)LineString/(Multi)Point : "+export_flags);
exportPolygonToWkt(export_flags, (Polygon) geometry, string);
return;
@@ -52,7 +52,7 @@ static void exportToWkt(int export_flags, Geometry geometry,
|| (export_flags & WktExportFlags.wktExportMultiPolygon) != 0
|| (export_flags & WktExportFlags.wktExportPoint) != 0
|| (export_flags & WktExportFlags.wktExportMultiPoint) != 0)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export a Polyline as (Multi)Polygon/(Multi)Point : "+export_flags);
exportPolylineToWkt(export_flags, (Polyline) geometry, string);
return;
@@ -62,7 +62,7 @@ static void exportToWkt(int export_flags, Geometry geometry,
|| (export_flags & WktExportFlags.wktExportMultiLineString) != 0
|| (export_flags & WktExportFlags.wktExportPolygon) != 0
|| (export_flags & WktExportFlags.wktExportMultiPolygon) != 0)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export a MultiPoint as (Multi)LineString/(Multi)Polygon: "+export_flags);
exportMultiPointToWkt(export_flags, (MultiPoint) geometry, string);
return;
@@ -72,7 +72,7 @@ static void exportToWkt(int export_flags, Geometry geometry,
|| (export_flags & WktExportFlags.wktExportMultiLineString) != 0
|| (export_flags & WktExportFlags.wktExportPolygon) != 0
|| (export_flags & WktExportFlags.wktExportMultiPolygon) != 0)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export a Point as (Multi)LineString/(Multi)Polygon: "+export_flags);
exportPointToWkt(export_flags, (Point) geometry, string);
return;
@@ -82,13 +82,13 @@ static void exportToWkt(int export_flags, Geometry geometry,
|| (export_flags & WktExportFlags.wktExportMultiLineString) != 0
|| (export_flags & WktExportFlags.wktExportPoint) != 0
|| (export_flags & WktExportFlags.wktExportMultiPoint) != 0)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export an Envelope as (Multi)LineString/(Multi)Point: "+export_flags);
exportEnvelopeToWkt(export_flags, (Envelope) geometry, string);
return;
default: {
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
}
@@ -149,7 +149,7 @@ static void exportPolygonToWkt(int export_flags, Polygon polygon,
if ((export_flags & WktExportFlags.wktExportPolygon) != 0) {
if (polygon_count > 1)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export a Polygon with specified export flags: "+export_flags);
polygonTaggedText_(precision, b_export_zs, b_export_ms, zs, ms,
position, path_flags, paths, path_count, string);
@@ -207,7 +207,7 @@ static void exportPolylineToWkt(int export_flags, Polyline polyline,
if ((export_flags & WktExportFlags.wktExportLineString) != 0) {
if (path_count > 1)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export a LineString with specified export flags: "+export_flags);
lineStringTaggedText_(precision, b_export_zs, b_export_ms, zs, ms,
position, path_flags, paths, string);
@@ -256,7 +256,7 @@ static void exportMultiPointToWkt(int export_flags, MultiPoint multipoint,
if ((export_flags & WktExportFlags.wktExportPoint) != 0) {
if (point_count > 1)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Cannot export a Point with specified export flags: "+export_flags);
pointTaggedTextFromMultiPoint_(precision, b_export_zs, b_export_ms,
zs, ms, position, string);
diff --git a/src/com/esri/core/geometry/OperatorFactory.java b/src/main/java/com/esri/core/geometry/OperatorFactory.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorFactory.java
rename to src/main/java/com/esri/core/geometry/OperatorFactory.java
index 680cdfee..66e6030a 100644
--- a/src/com/esri/core/geometry/OperatorFactory.java
+++ b/src/main/java/com/esri/core/geometry/OperatorFactory.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorFactoryLocal.java b/src/main/java/com/esri/core/geometry/OperatorFactoryLocal.java
similarity index 87%
rename from src/com/esri/core/geometry/OperatorFactoryLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorFactoryLocal.java
index 14709bda..04368b9d 100644
--- a/src/com/esri/core/geometry/OperatorFactoryLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorFactoryLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,9 +25,11 @@
package com.esri.core.geometry;
import com.esri.core.geometry.Operator.Type;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
@@ -35,8 +37,6 @@
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.util.HashMap;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParser;
/**
*An abstract class that represent the basic OperatorFactory interface.
@@ -54,8 +54,6 @@ public class OperatorFactoryLocal extends OperatorFactory {
new OperatorExportToJsonLocal());
st_supportedOperators.put(Type.ImportFromJson,
new OperatorImportFromJsonLocal());
- st_supportedOperators.put(Type.ImportMapGeometryFromJson,
- new OperatorImportFromJsonLocal());
st_supportedOperators.put(Type.ExportToESRIShape,
new OperatorExportToESRIShapeLocal());
st_supportedOperators.put(Type.ImportFromESRIShape,
@@ -63,6 +61,8 @@ public class OperatorFactoryLocal extends OperatorFactory {
st_supportedOperators.put(Type.Proximity2D,
new OperatorProximity2DLocal());
+ st_supportedOperators.put(Type.Centroid2D,
+ new OperatorCentroid2DLocal());
st_supportedOperators.put(Type.DensifyByLength,
new OperatorDensifyByLengthLocal());
@@ -83,6 +83,15 @@ public class OperatorFactoryLocal extends OperatorFactory {
st_supportedOperators.put(Type.Simplify, new OperatorSimplifyLocal());
st_supportedOperators.put(Type.Offset, new OperatorOffsetLocal());
+ st_supportedOperators.put(Type.GeodeticDensifyByLength,
+ new OperatorGeodeticDensifyLocal());
+
+ st_supportedOperators.put(Type.ShapePreservingDensify,
+ new OperatorShapePreservingDensifyLocal());
+
+ st_supportedOperators.put(Type.GeodesicBuffer,
+ new OperatorGeodesicBufferLocal());
+
st_supportedOperators.put(Type.GeodeticLength,
new OperatorGeodeticLengthLocal());
st_supportedOperators.put(Type.GeodeticArea,
@@ -118,23 +127,14 @@ public class OperatorFactoryLocal extends OperatorFactory {
new OperatorConvexHullLocal());
st_supportedOperators.put(Type.Boundary, new OperatorBoundaryLocal());
- // LabelPoint,
- // Simplify,
- //
+ // LabelPoint, - not ported
}
private OperatorFactoryLocal() {
- m_bNewTopo = false;// use sg by default
- // m_bNewTopo = true;//use sg by default
}
- /**
- * A temporary way to switch to new topo engine from SG. Set it to true, to
- * switch. Need to be changed once at the startup of the program.
- */
- boolean m_bNewTopo;
/**
*Returns a reference to the singleton.
@@ -183,32 +183,47 @@ public static MapGeometry loadGeometryFromJSONFileDbg(String file_name) {
}
String jsonString = null;
+ Reader reader = null;
try {
FileInputStream stream = new FileInputStream(file_name);
- Reader reader = new BufferedReader(new InputStreamReader(stream));
+ reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
char[] buffer = new char[8192];
int read;
while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
builder.append(buffer, 0, read);
}
- stream.close();
jsonString = builder.toString();
} catch (Exception ex) {
}
+ finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ MapGeometry mapGeom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, jsonString);
+ return mapGeom;
+ }
+
+ public static MapGeometry loadGeometryFromJSONStringDbg(String json) {
+ if (json == null) {
+ throw new IllegalArgumentException();
+ }
- JsonFactory jf = new JsonFactory();
- JsonParser jp = null;
+ MapGeometry mapGeom = null;
try {
- jp = jf.createJsonParser(jsonString);
- jp.nextToken();
- } catch (Exception ex) {
+ mapGeom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, json);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e.toString());
}
- MapGeometry mapGeom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, jp);
return mapGeom;
}
-
+
public static Geometry loadGeometryFromEsriShapeDbg(String file_name) {
if (file_name == null) {
throw new IllegalArgumentException();
@@ -270,20 +285,28 @@ public static Geometry loadGeometryFromWKTFileDbg(String file_name) {
}
String s = null;
+ Reader reader = null;
try {
FileInputStream stream = new FileInputStream(file_name);
- Reader reader = new BufferedReader(new InputStreamReader(stream));
+ reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
char[] buffer = new char[8192];
int read;
while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
builder.append(buffer, 0, read);
}
- stream.close();
s = builder.toString();
} catch (Exception ex) {
}
+ finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ }
+ }
+ }
return OperatorImportFromWkt.local().execute(0, Geometry.Type.Unknown, s, null);
}
diff --git a/src/com/esri/core/geometry/OperatorGeneralize.java b/src/main/java/com/esri/core/geometry/OperatorGeneralize.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorGeneralize.java
rename to src/main/java/com/esri/core/geometry/OperatorGeneralize.java
index af6223bd..ce8c4703 100644
--- a/src/com/esri/core/geometry/OperatorGeneralize.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeneralize.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorGeneralizeCursor.java b/src/main/java/com/esri/core/geometry/OperatorGeneralizeCursor.java
similarity index 92%
rename from src/com/esri/core/geometry/OperatorGeneralizeCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorGeneralizeCursor.java
index 8e04928a..b0b31a5c 100644
--- a/src/com/esri/core/geometry/OperatorGeneralizeCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeneralizeCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -64,8 +64,6 @@ private Geometry Generalize(Geometry geom) {
if (geom.isEmpty())
return geom;
MultiPath mp = (MultiPath) geom;
- if (mp == null)
- throw new GeometryException("internal error");
MultiPath dstmp = (MultiPath) geom.createInstance();
Line line = new Line();
for (int ipath = 0, npath = mp.getPathCount(); ipath < npath; ipath++) {
@@ -113,19 +111,23 @@ private void GeneralizePath(MultiPathImpl mpsrc, int ipath,
if (!bClosed)
resultStack.add(stack.get(0));
- if (resultStack.size() == stack.size()) {
+ int rs_size = resultStack.size();
+ int path_size = mpsrc.getPathSize(ipath);
+ if (rs_size == path_size && rs_size == stack.size()) {
mpdst.addPath(mpsrc, ipath, true);
} else {
- if (resultStack.size() >= 2) {
- if (m_bRemoveDegenerateParts && resultStack.size() == 2) {
- if (bClosed)
+ if (resultStack.size() > 0) {
+ if (m_bRemoveDegenerateParts && resultStack.size() <= 2) {
+ if (bClosed || resultStack.size() == 1)
return;
+
double d = Point2D.distance(
mpsrc.getXY(resultStack.get(0)),
mpsrc.getXY(resultStack.get(1)));
if (d <= m_maxDeviation)
return;
}
+
Point point = new Point();
for (int i = 0, n = resultStack.size(); i < n; i++) {
mpsrc.getPointByVal(resultStack.get(i), point);
@@ -136,8 +138,9 @@ private void GeneralizePath(MultiPathImpl mpsrc, int ipath,
}
if (bClosed) {
- if (!m_bRemoveDegenerateParts && resultStack.size() == 2)
+ for (int i = resultStack.size(); i < 3; i++)
mpdst.lineTo(point);
+
mpdst.closePathWithLine();
}
}
diff --git a/src/com/esri/core/geometry/OperatorGeneralizeLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeneralizeLocal.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorGeneralizeLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorGeneralizeLocal.java
index cf759c4b..c46e0f8c 100644
--- a/src/com/esri/core/geometry/OperatorGeneralizeLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeneralizeLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/OperatorGeodesicBuffer.java b/src/main/java/com/esri/core/geometry/OperatorGeodesicBuffer.java
new file mode 100644
index 00000000..03cbae60
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodesicBuffer.java
@@ -0,0 +1,71 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+abstract class OperatorGeodesicBuffer extends Operator {
+
+ @Override
+ public Operator.Type getType() {
+ return Operator.Type.GeodesicBuffer;
+ }
+
+ /**
+ * Creates a geodesic buffer around the input geometries
+ *
+ * @param inputGeometries The geometries to buffer.
+ * @param sr The Spatial_reference of the Geometries.
+ * @param curveType The geodetic curve type of the segments. If the curve_type is Geodetic_curve::shape_preserving, then the segments are densified in the projection where they are defined before
+ * buffering.
+ * @param distancesMeters The buffer distances in meters for the Geometries. If the size of the distances array is less than the number of geometries in the input_geometries, the last distance value
+ * is used for the rest of geometries.
+ * @param maxDeviationMeters The deviation offset to use for convergence. The geodesic arcs of the resulting buffer will be closer than the max deviation of the true buffer. Pass in NaN to use the
+ * default deviation.
+ * @param bReserved Must be false. Reserved for future development. Will throw an exception if not false.
+ * @param bUnion If True, the buffered geometries will be unioned, otherwise they wont be unioned.
+ * @param progressTracker Can be null. Allows to cancel lengthy operation.
+ * @return Geometry cursor over result buffers.
+ */
+ abstract public GeometryCursor execute(GeometryCursor inputGeometries, SpatialReference sr, int curveType, double[] distancesMeters, double maxDeviationMeters, boolean bReserved, boolean bUnion, ProgressTracker progressTracker);
+
+ /**
+ * Creates a geodesic buffer around the input geometry
+ *
+ * @param inputGeometry The geometry to buffer.
+ * @param sr The Spatial_reference of the Geometry.
+ * @param curveType The geodetic curve type of the segments. If the curve_type is Geodetic_curve::shape_preserving, then the segments are densified in the projection where they are defined before
+ * buffering.
+ * @param distanceMeters The buffer distance in meters for the Geometry.
+ * @param maxDeviationMeters The deviation offset to use for convergence. The geodesic arcs of the resulting buffer will be closer than the max deviation of the true buffer. Pass in NaN to use the
+ * default deviation.
+ * @param bReserved Must be false. Reserved for future development. Will throw an exception if not false.
+ * @param progressTracker Can be null. Allows to cancel lengthy operation.
+ * @return Returns result buffer.
+ */
+ abstract public Geometry execute(Geometry inputGeometry, SpatialReference sr, int curveType, double distanceMeters, double maxDeviationMeters, boolean bReserved, ProgressTracker progressTracker);
+
+ public static OperatorGeodesicBuffer local() {
+ return (OperatorGeodesicBuffer) OperatorFactoryLocal.getInstance()
+ .getOperator(Type.GeodesicBuffer);
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorGeodesicBufferLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodesicBufferLocal.java
new file mode 100644
index 00000000..7b9f97ba
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodesicBufferLocal.java
@@ -0,0 +1,44 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+//This is a stub
+class OperatorGeodesicBufferLocal extends OperatorGeodesicBuffer {
+
+ @Override
+ public GeometryCursor execute(GeometryCursor inputGeometries,
+ SpatialReference sr, int curveType, double[] distancesMeters,
+ double maxDeviationMeters, boolean bReserved, boolean bUnion,
+ ProgressTracker progressTracker) {
+ throw new GeometryException("not implemented");
+ }
+
+ @Override
+ public Geometry execute(Geometry inputGeometry, SpatialReference sr,
+ int curveType, double distanceMeters, double maxDeviationMeters,
+ boolean bReserved, ProgressTracker progressTracker) {
+ throw new GeometryException("not implemented");
+ }
+}
diff --git a/src/com/esri/core/geometry/OperatorGeodeticArea.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticArea.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorGeodeticArea.java
rename to src/main/java/com/esri/core/geometry/OperatorGeodeticArea.java
index 3e45ed36..ee2e0df7 100644
--- a/src/com/esri/core/geometry/OperatorGeodeticArea.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodeticArea.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorGeodeticAreaLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticAreaLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorGeodeticAreaLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorGeodeticAreaLocal.java
index 441f0ec0..12a3f805 100644
--- a/src/com/esri/core/geometry/OperatorGeodeticAreaLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodeticAreaLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyByLength.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyByLength.java
new file mode 100644
index 00000000..ca2d1087
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyByLength.java
@@ -0,0 +1,60 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+/**
+ * Densifies the line segments by length, making them run along specified geodetic curves.
+ *
+* Use this operator to construct geodetic curves.
+ */
+abstract class OperatorGeodeticDensifyByLength extends Operator {
+
+ @Override
+ public Type getType() {
+ return Type.GeodeticDensifyByLength;
+ }
+
+ /**
+ * Densifies input geometries. Attributes are interpolated along the scalar t-values of the input segments obtained from the length ratios along the densified segments.
+ *
+ * @param geoms The geometries to be densified.
+ * @param maxSegmentLengthMeters The maximum segment length (in meters) allowed. Must be a positive value.
+ * @param sr The SpatialReference of the Geometry.
+ * @param curveType The interpretation of a line connecting two points.
+ * @return Returns the densified geometries (It does nothing to geometries with dim less than 1, but simply passes them along).
+ *
+ * Note the behavior is not determined for any geodetic curve segments that connect two poles, or for loxodrome segments that connect to any pole.
+ */
+ public abstract GeometryCursor execute(GeometryCursor geoms, double maxSegmentLengthMeters, SpatialReference sr, int curveType, ProgressTracker progressTracker);
+
+ /**
+ * Same as above, but works with a single geometry.
+ */
+ public abstract Geometry execute(Geometry geom, double maxSegmentLengthMeters, SpatialReference sr, int curveType, ProgressTracker progressTracker);
+
+ public static OperatorGeodeticDensifyByLength local() {
+ return (OperatorGeodeticDensifyByLength) OperatorFactoryLocal.getInstance()
+ .getOperator(Type.GeodeticDensifyByLength);
+ }
+}
diff --git a/src/com/esri/core/geometry/OperatorExportToJsonLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyLocal.java
similarity index 60%
rename from src/com/esri/core/geometry/OperatorExportToJsonLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyLocal.java
index 32586c5f..f704c395 100644
--- a/src/com/esri/core/geometry/OperatorExportToJsonLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,21 +21,23 @@
email: contracts@esri.com
*/
+
package com.esri.core.geometry;
-class OperatorExportToJsonLocal extends OperatorExportToJson {
+//This is a stub
+class OperatorGeodeticDensifyLocal extends
+ OperatorGeodeticDensifyByLength {
@Override
- JsonCursor execute(SpatialReference spatialReference,
- GeometryCursor geometryCursor) {
- return new OperatorExportToJsonCursor(spatialReference, geometryCursor);
+ public GeometryCursor execute(GeometryCursor geoms,
+ double maxSegmentLengthMeters, SpatialReference sr, int curveType,
+ ProgressTracker progressTracker) {
+ throw new GeometryException("not implemented");
}
@Override
- public String execute(SpatialReference spatialReference, Geometry geometry) {
- SimpleGeometryCursor gc = new SimpleGeometryCursor(geometry);
- JsonCursor cursor = new OperatorExportToJsonCursor(spatialReference, gc);
- return cursor.next();
+ public Geometry execute(Geometry geom, double maxSegmentLengthMeters,
+ SpatialReference sr, int curveType, ProgressTracker progressTracker) {
+ throw new GeometryException("not implemented");
}
-
}
diff --git a/src/com/esri/core/geometry/OperatorGeodeticLength.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticLength.java
similarity index 71%
rename from src/com/esri/core/geometry/OperatorGeodeticLength.java
rename to src/main/java/com/esri/core/geometry/OperatorGeodeticLength.java
index d43fe141..268dbc5c 100644
--- a/src/com/esri/core/geometry/OperatorGeodeticLength.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodeticLength.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -38,23 +38,6 @@ public Type getType() {
return Operator.Type.GeodeticLength;
}
- /**
- * Calculates the geodetic length of each geometry in the geometry cursor.
- *
- * @param geoms
- * The geometry cursor to be iterated over to perform the
- * Geodetic Length calculation.
- * @param sr
- * The SpatialReference of the geometries.
- * @param geodeticCurveType
- * Use the {@link GeodeticCurveType} interface to choose the
- * interpretation of a line connecting two points.
- * @param progressTracker
- * @return Returns an array of the geoetic lengths of the geometries.
- */
- public abstract double[] execute(GeometryCursor geoms, SpatialReference sr,
- int geodeticCurveType, ProgressTracker progressTracker);
-
/**
* Calculates the geodetic length of the input Geometry.
*
diff --git a/src/com/esri/core/geometry/OperatorGeodeticLengthLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticLengthLocal.java
similarity index 82%
rename from src/com/esri/core/geometry/OperatorGeodeticLengthLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorGeodeticLengthLocal.java
index 4c57ca28..306e3c74 100644
--- a/src/com/esri/core/geometry/OperatorGeodeticLengthLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodeticLengthLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,12 +26,6 @@
//This is a stub
class OperatorGeodeticLengthLocal extends OperatorGeodeticLength {
- @Override
- public double[] execute(GeometryCursor geoms, SpatialReference sr,
- int geodeticCurveType, ProgressTracker progressTracker) {
- throw new GeometryException("not implemented");
- }
-
@Override
public double execute(Geometry geom, SpatialReference sr,
int geodeticCurveType, ProgressTracker progressTracker) {
diff --git a/src/com/esri/core/geometry/OperatorImportFromESRIShape.java b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShape.java
similarity index 64%
rename from src/com/esri/core/geometry/OperatorImportFromESRIShape.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromESRIShape.java
index 32c7f778..75bc1375 100644
--- a/src/com/esri/core/geometry/OperatorImportFromESRIShape.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShape.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -39,7 +39,11 @@ public Type getType() {
/**
* Performs the ImportFromESRIShape operation on a stream of shape buffers
- *
+ * @param importFlags Use the {@link ShapeImportFlags} interface. The default is 0, which means geometry comes from a trusted source and is topologically simple.
+ * If the geometry comes from non-trusted source (that is it can be non-simple), pass ShapeImportNonTrusted.
+ * @param type The geometry type that you want to import. Use the {@link Geometry.Type} enum. It can be Geometry.Type.Unknown if the type of geometry has to be
+ * figured out from the shape buffer.
+ * @param shapeBuffers The cursor over shape buffers that hold the Geometries in ESRIShape format.
* @return Returns a GeometryCursor.
*/
abstract GeometryCursor execute(int importFlags, Geometry.Type type,
@@ -47,8 +51,10 @@ abstract GeometryCursor execute(int importFlags, Geometry.Type type,
/**
* Performs the ImportFromESRIShape operation.
- * @param importFlags Use the {@link ShapeImportFlags} interface.
- * @param type Use the {@link Geometry.Type} enum.
+ * @param importFlags Use the {@link ShapeImportFlags} interface. The default is 0, which means geometry comes from a trusted source and is topologically simple.
+ * If the geometry comes from non-trusted source (that is it can be non-simple), pass ShapeImportNonTrusted.
+ * @param type The geometry type that you want to import. Use the {@link Geometry.Type} enum. It can be Geometry.Type.Unknown if the type of geometry has to be
+ * figured out from the shape buffer.
* @param shapeBuffer The buffer holding the Geometry in ESRIShape format.
* @return Returns the imported Geometry.
*/
diff --git a/src/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java
similarity index 88%
rename from src/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java
index 982abe03..2db25375 100644
--- a/src/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -63,116 +63,116 @@ public int getGeometryID() {
}
private Geometry importFromESRIShape(ByteBuffer shapeBuffer) {
- // read type
- int shapetype = shapeBuffer.getInt(0);
-
- // Extract general type and modifiers
- int generaltype;
- int modifiers;
- switch (shapetype & ShapeModifiers.ShapeBasicTypeMask) {
- // Polygon
- case ShapeType.ShapePolygon:
- generaltype = ShapeType.ShapeGeneralPolygon;
- modifiers = 0;
- break;
- case ShapeType.ShapePolygonZM:
- generaltype = ShapeType.ShapeGeneralPolygon;
- modifiers = ShapeModifiers.ShapeHasZs | ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapePolygonM:
- generaltype = ShapeType.ShapeGeneralPolygon;
- modifiers = ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapePolygonZ:
- generaltype = ShapeType.ShapeGeneralPolygon;
- modifiers = ShapeModifiers.ShapeHasZs;
- break;
- case ShapeType.ShapeGeneralPolygon:
- generaltype = ShapeType.ShapeGeneralPolygon;
- modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
- break;
-
- // Polyline
- case ShapeType.ShapePolyline:
- generaltype = ShapeType.ShapeGeneralPolyline;
- modifiers = 0;
- break;
- case ShapeType.ShapePolylineZM:
- generaltype = ShapeType.ShapeGeneralPolyline;
- modifiers = ShapeModifiers.ShapeHasZs
- | (int) ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapePolylineM:
- generaltype = ShapeType.ShapeGeneralPolyline;
- modifiers = ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapePolylineZ:
- generaltype = ShapeType.ShapeGeneralPolyline;
- modifiers = ShapeModifiers.ShapeHasZs;
- break;
- case ShapeType.ShapeGeneralPolyline:
- generaltype = ShapeType.ShapeGeneralPolyline;
- modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
- break;
-
- // MultiPoint
- case ShapeType.ShapeMultiPoint:
- generaltype = ShapeType.ShapeGeneralMultiPoint;
- modifiers = 0;
- break;
- case ShapeType.ShapeMultiPointZM:
- generaltype = ShapeType.ShapeGeneralMultiPoint;
- modifiers = (int) ShapeModifiers.ShapeHasZs
- | (int) ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapeMultiPointM:
- generaltype = ShapeType.ShapeGeneralMultiPoint;
- modifiers = ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapeMultiPointZ:
- generaltype = ShapeType.ShapeGeneralMultiPoint;
- modifiers = ShapeModifiers.ShapeHasZs;
- break;
- case ShapeType.ShapeGeneralMultiPoint:
- generaltype = ShapeType.ShapeGeneralMultiPoint;
- modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
- break;
-
- // Point
- case ShapeType.ShapePoint:
- generaltype = ShapeType.ShapeGeneralPoint;
- modifiers = 0;
- break;
- case ShapeType.ShapePointZM:
- generaltype = ShapeType.ShapeGeneralPoint;
- modifiers = ShapeModifiers.ShapeHasZs
- | (int) ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapePointM:
- generaltype = ShapeType.ShapeGeneralPoint;
- modifiers = ShapeModifiers.ShapeHasMs;
- break;
- case ShapeType.ShapePointZ:
- generaltype = ShapeType.ShapeGeneralPoint;
- modifiers = ShapeModifiers.ShapeHasZs;
- break;
- case ShapeType.ShapeGeneralPoint:
- generaltype = ShapeType.ShapeGeneralPoint;
- modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
- break;
-
- // Null Geometry
- case ShapeType.ShapeNull:
- return null;
-
- default:
- throw new GeometryException("invalid shape type");
- }
-
ByteOrder initialOrder = shapeBuffer.order();
shapeBuffer.order(ByteOrder.LITTLE_ENDIAN);
try {
+ // read type
+ int shapetype = shapeBuffer.getInt(0);
+
+ // Extract general type and modifiers
+ int generaltype;
+ int modifiers;
+ switch (shapetype & ShapeModifiers.ShapeBasicTypeMask) {
+ // Polygon
+ case ShapeType.ShapePolygon:
+ generaltype = ShapeType.ShapeGeneralPolygon;
+ modifiers = 0;
+ break;
+ case ShapeType.ShapePolygonZM:
+ generaltype = ShapeType.ShapeGeneralPolygon;
+ modifiers = ShapeModifiers.ShapeHasZs | ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapePolygonM:
+ generaltype = ShapeType.ShapeGeneralPolygon;
+ modifiers = ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapePolygonZ:
+ generaltype = ShapeType.ShapeGeneralPolygon;
+ modifiers = ShapeModifiers.ShapeHasZs;
+ break;
+ case ShapeType.ShapeGeneralPolygon:
+ generaltype = ShapeType.ShapeGeneralPolygon;
+ modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
+ break;
+
+ // Polyline
+ case ShapeType.ShapePolyline:
+ generaltype = ShapeType.ShapeGeneralPolyline;
+ modifiers = 0;
+ break;
+ case ShapeType.ShapePolylineZM:
+ generaltype = ShapeType.ShapeGeneralPolyline;
+ modifiers = ShapeModifiers.ShapeHasZs
+ | (int) ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapePolylineM:
+ generaltype = ShapeType.ShapeGeneralPolyline;
+ modifiers = ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapePolylineZ:
+ generaltype = ShapeType.ShapeGeneralPolyline;
+ modifiers = ShapeModifiers.ShapeHasZs;
+ break;
+ case ShapeType.ShapeGeneralPolyline:
+ generaltype = ShapeType.ShapeGeneralPolyline;
+ modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
+ break;
+
+ // MultiPoint
+ case ShapeType.ShapeMultiPoint:
+ generaltype = ShapeType.ShapeGeneralMultiPoint;
+ modifiers = 0;
+ break;
+ case ShapeType.ShapeMultiPointZM:
+ generaltype = ShapeType.ShapeGeneralMultiPoint;
+ modifiers = (int) ShapeModifiers.ShapeHasZs
+ | (int) ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapeMultiPointM:
+ generaltype = ShapeType.ShapeGeneralMultiPoint;
+ modifiers = ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapeMultiPointZ:
+ generaltype = ShapeType.ShapeGeneralMultiPoint;
+ modifiers = ShapeModifiers.ShapeHasZs;
+ break;
+ case ShapeType.ShapeGeneralMultiPoint:
+ generaltype = ShapeType.ShapeGeneralMultiPoint;
+ modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
+ break;
+
+ // Point
+ case ShapeType.ShapePoint:
+ generaltype = ShapeType.ShapeGeneralPoint;
+ modifiers = 0;
+ break;
+ case ShapeType.ShapePointZM:
+ generaltype = ShapeType.ShapeGeneralPoint;
+ modifiers = ShapeModifiers.ShapeHasZs
+ | (int) ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapePointM:
+ generaltype = ShapeType.ShapeGeneralPoint;
+ modifiers = ShapeModifiers.ShapeHasMs;
+ break;
+ case ShapeType.ShapePointZ:
+ generaltype = ShapeType.ShapeGeneralPoint;
+ modifiers = ShapeModifiers.ShapeHasZs;
+ break;
+ case ShapeType.ShapeGeneralPoint:
+ generaltype = ShapeType.ShapeGeneralPoint;
+ modifiers = shapetype & ShapeModifiers.ShapeModifierMask;
+ break;
+
+ // Null Geometry
+ case ShapeType.ShapeNull:
+ return null;
+
+ default:
+ throw new GeometryException("invalid shape type");
+ }
+
switch (generaltype) {
case ShapeType.ShapeGeneralPolygon:
if (m_type != Geometry.GeometryType.Polygon
diff --git a/src/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java
index 4bcdd3a0..16c2013f 100644
--- a/src/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorImportFromGeoJson.java b/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJson.java
similarity index 66%
rename from src/com/esri/core/geometry/OperatorImportFromGeoJson.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromGeoJson.java
index 9032c913..2a25215d 100644
--- a/src/com/esri/core/geometry/OperatorImportFromGeoJson.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJson.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,9 +23,8 @@
*/
package com.esri.core.geometry;
-import org.json.JSONException;
-
public abstract class OperatorImportFromGeoJson extends Operator {
+
@Override
public Type getType() {
return Type.ImportFromGeoJson;
@@ -33,29 +32,38 @@ public Type getType() {
/**
* Performs the ImportFromGeoJson operation.
+ *
+ * @param type Use the {@link Geometry.Type} enum.
+ * @param jsonReader The JSONReader.
+ * @return Returns the imported MapGeometry.
+ * @throws JsonGeometryException
+ */
+ public abstract MapGeometry execute(int importFlags, Geometry.Type type, JsonReader jsonReader, ProgressTracker progressTracker);
+
+ /**
+ * Deprecated, use version without import_flags.
+ *
+ * Performs the ImportFromGeoJson operation.
+ *
* @param import_flags Use the {@link GeoJsonImportFlags} interface.
- * @param type Use the {@link Geometry.Type} enum.
+ * @param type Use the {@link Geometry.Type} enum.
* @param geoJsonString The string holding the Geometry in geoJson format.
- * @return Returns the imported Geometry.
- * @throws JSONException
+ * @return Returns the imported MapGeometry.
+ *
*/
- public abstract MapGeometry execute(int import_flags, Geometry.Type type,
- String geoJsonString, ProgressTracker progress_tracker)
- throws JSONException;
+ public abstract MapGeometry execute(int import_flags, Geometry.Type type, String geoJsonString, ProgressTracker progress_tracker);
/**
+ *
* Performs the ImportFromGeoJson operation.
+ *
* @param import_flags Use the {@link GeoJsonImportFlags} interface.
* @param geoJsonString The string holding the Geometry in geoJson format.
* @return Returns the imported MapOGCStructure.
- * @throws JSONException
*/
- public abstract MapOGCStructure executeOGC(int import_flags,
- String geoJsonString, ProgressTracker progress_tracker)
- throws JSONException;
+ public abstract MapOGCStructure executeOGC(int import_flags, String geoJsonString, ProgressTracker progress_tracker);
public static OperatorImportFromGeoJson local() {
- return (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance()
- .getOperator(Type.ImportFromGeoJson);
+ return (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Type.ImportFromGeoJson);
}
}
diff --git a/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJsonLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJsonLocal.java
new file mode 100644
index 00000000..78e9c8b1
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJsonLocal.java
@@ -0,0 +1,1319 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.VertexDescription.Semantics;
+import java.util.ArrayList;
+
+class OperatorImportFromGeoJsonLocal extends OperatorImportFromGeoJson {
+ static enum GeoJsonType {
+ Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection;
+ static GeoJsonType fromGeoJsonValue(int v) {
+ return GeoJsonType.values()[v - 1];
+ }
+
+ public int geogsjonvalue() {
+ return ordinal() + 1;
+ }
+ };
+
+ static interface GeoJsonValues {
+ public final static int Point = GeoJsonType.Point.geogsjonvalue();
+ public final static int LineString = GeoJsonType.LineString.geogsjonvalue();
+ public final static int Polygon = GeoJsonType.Polygon.geogsjonvalue();
+ public final static int MultiPoint = GeoJsonType.MultiPoint.geogsjonvalue();
+ public final static int MultiLineString = GeoJsonType.MultiLineString.geogsjonvalue();
+ public final static int MultiPolygon = GeoJsonType.MultiPolygon.geogsjonvalue();
+ public final static int GeometryCollection = GeoJsonType.GeometryCollection.geogsjonvalue();
+ };
+
+ @Override
+ public MapGeometry execute(int importFlags, Geometry.Type type,
+ String geoJsonString, ProgressTracker progressTracker)
+ throws JsonGeometryException {
+ MapGeometry map_geometry = OperatorImportFromGeoJsonHelper
+ .importFromGeoJson(importFlags, type, JsonParserReader.createFromString(geoJsonString), progressTracker, false);
+ return map_geometry;
+ }
+
+ @Override
+ public MapGeometry execute(int importFlags, Geometry.Type type,
+ JsonReader jsonReader, ProgressTracker progressTracker)
+ throws JsonGeometryException {
+ if (jsonReader == null)
+ return null;
+
+ return OperatorImportFromGeoJsonHelper.importFromGeoJson(importFlags,
+ type, jsonReader, progressTracker, false);
+ }
+
+ static final class OperatorImportFromGeoJsonHelper {
+
+ private AttributeStreamOfDbl m_position;
+ private AttributeStreamOfDbl m_zs;
+ private AttributeStreamOfDbl m_ms;
+ private AttributeStreamOfInt32 m_paths;
+ private AttributeStreamOfInt8 m_path_flags;
+ private Point m_point; // special case for Points
+ private boolean m_b_has_zs;
+ private boolean m_b_has_ms;
+ private boolean m_b_has_zs_known;
+ private boolean m_b_has_ms_known;
+ private int m_num_embeddings;
+
+ int m_ogcType;
+
+ OperatorImportFromGeoJsonHelper() {
+ m_position = null;
+ m_zs = null;
+ m_ms = null;
+ m_paths = null;
+ m_path_flags = null;
+ m_point = null;
+ m_b_has_zs = false;
+ m_b_has_ms = false;
+ m_b_has_zs_known = false;
+ m_b_has_ms_known = false;
+ m_num_embeddings = 0;
+ m_ogcType = 0;
+ }
+
+ static MapGeometry importFromGeoJson(int importFlags,
+ Geometry.Type type, JsonReader json_iterator,
+ ProgressTracker progress_tracker, boolean skip_coordinates)
+ throws JsonGeometryException {
+ OperatorImportFromGeoJsonHelper geo_json_helper = new OperatorImportFromGeoJsonHelper();
+ MapOGCStructure ms = geo_json_helper.importFromGeoJsonImpl(
+ importFlags, type, json_iterator, progress_tracker,
+ skip_coordinates, 0);
+
+ if (geo_json_helper.m_ogcType == GeoJsonValues.GeometryCollection && !skip_coordinates)
+ throw new JsonGeometryException("parsing error");
+
+ return new MapGeometry(ms.m_ogcStructure.m_geometry,
+ ms.m_spatialReference);
+ }
+
+ static MapOGCStructure importFromGeoJson(int importFlags,
+ Geometry.Type type, JsonReader json_iterator,
+ ProgressTracker progress_tracker, boolean skip_coordinates,
+ int recursion) throws JsonGeometryException {
+ OperatorImportFromGeoJsonHelper geo_json_helper = new OperatorImportFromGeoJsonHelper();
+ MapOGCStructure ms = geo_json_helper.importFromGeoJsonImpl(
+ importFlags, type, json_iterator, progress_tracker,
+ skip_coordinates, recursion);
+
+ if (geo_json_helper.m_ogcType == GeoJsonValues.GeometryCollection && !skip_coordinates)
+ throw new JsonGeometryException("parsing error");
+
+ return ms;
+ }
+ MapOGCStructure importFromGeoJsonImpl(int importFlags,
+ Geometry.Type type, JsonReader json_iterator,
+ ProgressTracker progress_tracker, boolean skip_coordinates,
+ int recursion) throws JsonGeometryException {
+ OperatorImportFromGeoJsonHelper geo_json_helper = this;
+ boolean b_type_found = false;
+ boolean b_coordinates_found = false;
+ boolean b_crs_found = false;
+ boolean b_crsURN_found = false;
+ boolean b_geometry_collection = false;
+ boolean b_geometries_found = false;
+ GeoJsonType geo_json_type = null;
+
+ Geometry geometry = null;
+ SpatialReference spatial_reference = null;
+
+ JsonReader.Token current_token;
+ String field_name = null;
+ MapOGCStructure ms = new MapOGCStructure();
+
+ while ((current_token = json_iterator.nextToken()) != JsonReader.Token.END_OBJECT) {
+ field_name = json_iterator.currentString();
+
+ if (field_name.equals("type")) {
+ if (b_type_found) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_type_found = true;
+ current_token = json_iterator.nextToken();
+
+ if (current_token != JsonReader.Token.VALUE_STRING) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ String s = json_iterator.currentString();
+ try {
+ geo_json_type = GeoJsonType.valueOf(s);
+ } catch (Exception ex) {
+ throw new JsonGeometryException(s);
+ }
+
+ if (geo_json_type == GeoJsonType.GeometryCollection) {
+ if (type != Geometry.Type.Unknown)
+ throw new JsonGeometryException("parsing error");
+
+ b_geometry_collection = true;
+ }
+ } else if (field_name.equals("geometries")) {
+ b_geometries_found = true;
+ if (type != Geometry.Type.Unknown)
+ throw new JsonGeometryException("parsing error");
+
+ if (recursion > 10) {
+ throw new JsonGeometryException("deep geojson");
+ }
+
+ if (skip_coordinates) {
+ json_iterator.skipChildren();
+ } else {
+ current_token = json_iterator.nextToken();
+
+ ms.m_ogcStructure = new OGCStructure();
+ ms.m_ogcStructure.m_type = GeoJsonValues.GeometryCollection;
+ ms.m_ogcStructure.m_structures = new ArrayList(
+ 0);
+
+ if (current_token == JsonReader.Token.START_ARRAY) {
+ current_token = json_iterator.nextToken();
+ while (current_token != JsonReader.Token.END_ARRAY) {
+ MapOGCStructure child = importFromGeoJson(
+ importFlags
+ | GeoJsonImportFlags.geoJsonImportSkipCRS,
+ type, json_iterator,
+ progress_tracker, false,
+ recursion + 1);
+ ms.m_ogcStructure.m_structures
+ .add(child.m_ogcStructure);
+
+ current_token = json_iterator.nextToken();
+ }
+ }
+ else if (current_token != JsonReader.Token.VALUE_NULL) {
+ throw new JsonGeometryException("parsing error");
+ }
+ }
+ } else if (field_name.equals("coordinates")) {
+
+ if (b_coordinates_found) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_coordinates_found = true;
+ current_token = json_iterator.nextToken();
+
+ if (skip_coordinates) {
+ json_iterator.skipChildren();
+ } else {// According to the spec, the value of the
+ // coordinates must be an array. However, I do an
+ // extra check for null too.
+ if (current_token != JsonReader.Token.VALUE_NULL) {
+ if (current_token != JsonReader.Token.START_ARRAY) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ geo_json_helper.import_coordinates_(json_iterator,
+ progress_tracker);
+ }
+ }
+ } else if (field_name.equals("crs")) {
+ if (b_crs_found || b_crsURN_found) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_crs_found = true;
+ current_token = json_iterator.nextToken();
+
+ if ((importFlags & GeoJsonImportFlags.geoJsonImportSkipCRS) == 0)
+ spatial_reference = importSpatialReferenceFromCrs(
+ json_iterator, progress_tracker);
+ else
+ json_iterator.skipChildren();
+ } else if (field_name.equals("crsURN")) {
+ if (b_crs_found || b_crsURN_found) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_crsURN_found = true;
+ current_token = json_iterator.nextToken();
+
+ spatial_reference = importSpatialReferenceFromCrsUrn_(
+ json_iterator, progress_tracker);
+ } else {
+ json_iterator.nextToken();
+ json_iterator.skipChildren();
+ }
+ }
+
+ // According to the spec, a GeoJSON object must have both a type and
+ // a coordinates array
+ if (!b_type_found || (!b_geometry_collection && !b_coordinates_found && !skip_coordinates)) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ if ((!b_geometry_collection && b_geometries_found) || (b_geometry_collection && !b_geometries_found)) {
+ throw new JsonGeometryException("parsing error");//found "geometries" but did not see "GeometryCollection"
+ }
+
+
+ if (!skip_coordinates && !b_geometry_collection) {
+ geometry = geo_json_helper.createGeometry_(geo_json_type,
+ type.value());
+
+ ms.m_ogcStructure = new OGCStructure();
+ ms.m_ogcStructure.m_type = m_ogcType;
+ ms.m_ogcStructure.m_geometry = geometry;
+ }
+
+ if (!b_crs_found
+ && !b_crsURN_found
+ && ((importFlags & GeoJsonImportFlags.geoJsonImportSkipCRS) == 0)
+ && ((importFlags & GeoJsonImportFlags.geoJsonImportNoWGS84Default) == 0)) {
+ spatial_reference = SpatialReference.create(4326); // the spec
+ // gives a
+ // default
+ // of 4326
+ // if no crs
+ // is given
+ }
+
+ ms.m_spatialReference = spatial_reference;
+ return ms;
+ }
+
+ // We have to import the coordinates in the most general way possible to
+ // not assume the type of geometry we're parsing.
+ // JSON allows for unordered objects, so it's possible that the
+ // coordinates array can come before the type tag when parsing
+ // sequentially, otherwise
+ // we would have to parse using a JSON_object, which would be easier,
+ // but not as space/time efficient. So this function blindly imports the
+ // coordinates
+ // into the attribute stream(s), and will later assign them to a
+ // geometry after the type tag is found.
+ private void import_coordinates_(JsonReader json_iterator,
+ ProgressTracker progress_tracker) throws JsonGeometryException {
+ assert (json_iterator.currentToken() == JsonReader.Token.START_ARRAY);
+
+ int coordinates_level_lower = 1;
+ int coordinates_level_upper = 4;
+
+ json_iterator.nextToken();
+
+ while (json_iterator.currentToken() != JsonReader.Token.END_ARRAY) {
+ if (isDouble_(json_iterator)) {
+ if (coordinates_level_upper > 1) {
+ coordinates_level_upper = 1;
+ }
+ } else if (json_iterator.currentToken() == JsonReader.Token.START_ARRAY) {
+ if (coordinates_level_lower < 2) {
+ coordinates_level_lower = 2;
+ }
+ } else {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ if (coordinates_level_lower > coordinates_level_upper) {
+ throw new IllegalArgumentException("invalid argument");
+ }
+
+ if (coordinates_level_lower == coordinates_level_upper
+ && coordinates_level_lower == 1) {// special
+ // code
+ // for
+ // Points
+ readCoordinateAsPoint_(json_iterator);
+ } else {
+ boolean b_add_path_level_3 = true;
+ boolean b_polygon_start_level_4 = true;
+
+ assert (json_iterator.currentToken() == JsonReader.Token.START_ARRAY);
+ json_iterator.nextToken();
+
+ while (json_iterator.currentToken() != JsonReader.Token.END_ARRAY) {
+ if (isDouble_(json_iterator)) {
+ if (coordinates_level_upper > 2) {
+ coordinates_level_upper = 2;
+ }
+ } else if (json_iterator.currentToken() == JsonReader.Token.START_ARRAY) {
+ if (coordinates_level_lower < 3) {
+ coordinates_level_lower = 3;
+ }
+ } else {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ if (coordinates_level_lower > coordinates_level_upper) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ if (coordinates_level_lower == coordinates_level_upper
+ && coordinates_level_lower == 2) {// LineString
+ // or
+ // MultiPoint
+ addCoordinate_(json_iterator);
+ } else {
+ boolean b_add_path_level_4 = true;
+
+ assert (json_iterator.currentToken() == JsonReader.Token.START_ARRAY);
+ json_iterator.nextToken();
+
+ while (json_iterator.currentToken() != JsonReader.Token.END_ARRAY) {
+ if (isDouble_(json_iterator)) {
+ if (coordinates_level_upper > 3) {
+ coordinates_level_upper = 3;
+ }
+ } else if (json_iterator.currentToken() == JsonReader.Token.START_ARRAY) {
+ if (coordinates_level_lower < 4) {
+ coordinates_level_lower = 4;
+ }
+ } else {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ if (coordinates_level_lower > coordinates_level_upper) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ if (coordinates_level_lower == coordinates_level_upper
+ && coordinates_level_lower == 3) {// Polygon
+ // or
+ // MultiLineString
+ if (b_add_path_level_3) {
+ addPath_();
+ b_add_path_level_3 = false;
+ }
+
+ addCoordinate_(json_iterator);
+ } else {
+ assert (json_iterator.currentToken() == JsonReader.Token.START_ARRAY);
+ json_iterator.nextToken();
+
+ if (json_iterator.currentToken() != JsonReader.Token.END_ARRAY) {
+ if (!isDouble_(json_iterator)) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ assert (coordinates_level_lower == coordinates_level_upper && coordinates_level_lower == 4);
+ // MultiPolygon
+
+ if (b_add_path_level_4) {
+ addPath_();
+ addPathFlag_(b_polygon_start_level_4);
+ b_add_path_level_4 = false;
+ b_polygon_start_level_4 = false;
+ }
+
+ addCoordinate_(json_iterator);
+ }
+
+ json_iterator.nextToken();
+ }
+ }
+
+ json_iterator.nextToken();
+ }
+ }
+
+ json_iterator.nextToken();
+ }
+ }
+
+ if (m_paths != null) {
+ m_paths.add(m_position.size() / 2); // add final path size
+ }
+ if (m_path_flags != null) {
+ m_path_flags.add((byte) 0); // to match the paths size
+ }
+
+ m_num_embeddings = coordinates_level_lower;
+ }
+
+ private void readCoordinateAsPoint_(JsonReader json_iterator)
+ throws JsonGeometryException {
+ assert (isDouble_(json_iterator));
+
+ m_point = new Point();
+
+ double x = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ double y = readDouble_(json_iterator);
+ json_iterator.nextToken();
+
+ if (NumberUtils.isNaN(y)) {
+ x = NumberUtils.NaN();
+ }
+
+ m_point.setXY(x, y);
+
+ if (isDouble_(json_iterator)) {
+ double z = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ m_point.setZ(z);
+ }
+
+ if (isDouble_(json_iterator)) {
+ double m = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ m_point.setM(m);
+ }
+
+ if (json_iterator.currentToken() != JsonReader.Token.END_ARRAY) {
+ throw new JsonGeometryException("parsing error");
+ }
+ }
+
+ private void addCoordinate_(JsonReader json_iterator)
+ throws JsonGeometryException {
+ assert (isDouble_(json_iterator));
+
+ if (m_position == null) {
+ m_position = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(0);
+ }
+
+ double x = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ double y = readDouble_(json_iterator);
+ json_iterator.nextToken();
+
+ int size = m_position.size();
+
+ m_position.add(x);
+ m_position.add(y);
+
+ if (isDouble_(json_iterator)) {
+ if (!m_b_has_zs_known) {
+ m_b_has_zs_known = true;
+ m_b_has_zs = true;
+ m_zs = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(0);
+ } else {
+ if (!m_b_has_zs) {
+ m_zs = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(size >> 1,
+ VertexDescription
+ .getDefaultValue(Semantics.Z));
+ m_b_has_zs = true;
+ }
+ }
+
+ double z = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ m_zs.add(z);
+ } else {
+ if (!m_b_has_zs_known) {
+ m_b_has_zs_known = true;
+ m_b_has_zs = false;
+ } else {
+ if (m_b_has_zs) {
+ m_zs.add(VertexDescription.getDefaultValue(Semantics.Z));
+ }
+ }
+ }
+
+ if (isDouble_(json_iterator)) {
+ if (!m_b_has_ms_known) {
+ m_b_has_ms_known = true;
+ m_b_has_ms = true;
+ m_ms = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(0);
+ } else {
+ if (!m_b_has_ms) {
+ m_ms = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(size >> 1,
+ VertexDescription
+ .getDefaultValue(Semantics.M));
+ m_b_has_ms = true;
+ }
+ }
+
+ double m = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ m_ms.add(m);
+ } else {
+ if (!m_b_has_ms_known) {
+ m_b_has_ms_known = true;
+ m_b_has_ms = false;
+ } else {
+ if (m_b_has_ms) {
+ m_zs.add(VertexDescription.getDefaultValue(Semantics.M));
+ }
+ }
+ }
+
+ if (json_iterator.currentToken() != JsonReader.Token.END_ARRAY) {
+ throw new JsonGeometryException("parsing error");
+ }
+ }
+
+ private void addPath_() {
+ if (m_paths == null) {
+ m_paths = (AttributeStreamOfInt32) AttributeStreamBase
+ .createIndexStream(0);
+ }
+
+ if (m_position == null) {
+ m_paths.add(0);
+ } else {
+ m_paths.add(m_position.size() / 2);
+ }
+ }
+
+ private void addPathFlag_(boolean b_polygon_start) {
+ if (m_path_flags == null) {
+ m_path_flags = (AttributeStreamOfInt8) AttributeStreamBase
+ .createByteStream(0);
+ }
+
+ if (b_polygon_start) {
+ m_path_flags
+ .add((byte) (PathFlags.enumClosed | PathFlags.enumOGCStartPolygon));
+ } else {
+ m_path_flags.add((byte) PathFlags.enumClosed);
+ }
+ }
+
+ private double readDouble_(JsonReader json_iterator)
+ throws JsonGeometryException {
+ JsonReader.Token current_token = json_iterator.currentToken();
+ if (current_token == JsonReader.Token.VALUE_NULL
+ || (current_token == JsonReader.Token.VALUE_STRING && json_iterator
+ .currentString().equals("NaN"))) {
+ return NumberUtils.NaN();
+ } else {
+ return json_iterator.currentDoubleValue();
+ }
+ }
+
+ private boolean isDouble_(JsonReader json_iterator)
+ throws JsonGeometryException {
+ JsonReader.Token current_token = json_iterator.currentToken();
+
+ if (current_token == JsonReader.Token.VALUE_NUMBER_FLOAT) {
+ return true;
+ }
+
+ if (current_token == JsonReader.Token.VALUE_NUMBER_INT) {
+ return true;
+ }
+
+ if (current_token == JsonReader.Token.VALUE_NULL
+ || (current_token == JsonReader.Token.VALUE_STRING && json_iterator
+ .currentString().equals("NaN"))) {
+ return true;
+ }
+
+ return false;
+ }
+
+ //does not accept GeometryCollection
+ private Geometry createGeometry_(GeoJsonType geo_json_type, int type)
+ throws JsonGeometryException {
+ Geometry geometry;
+
+ if (type != Geometry.GeometryType.Unknown) {
+ switch (type) {
+ case Geometry.GeometryType.Polygon:
+ if (geo_json_type != GeoJsonType.MultiPolygon
+ && geo_json_type != GeoJsonType.Polygon) {
+ throw new GeometryException("invalid shape type");
+ }
+ break;
+ case Geometry.GeometryType.Polyline:
+ if (geo_json_type != GeoJsonType.MultiLineString
+ && geo_json_type != GeoJsonType.LineString) {
+ throw new GeometryException("invalid shape type");
+ }
+ break;
+ case Geometry.GeometryType.MultiPoint:
+ if (geo_json_type != GeoJsonType.MultiPoint) {
+ throw new GeometryException("invalid shape type");
+ }
+ break;
+ case Geometry.GeometryType.Point:
+ if (geo_json_type != GeoJsonType.Point) {
+ throw new GeometryException("invalid shape type");
+ }
+ break;
+ default:
+ throw new GeometryException("invalid shape type");
+ }
+ }
+
+ m_ogcType = geo_json_type.geogsjonvalue();
+ if (geo_json_type == GeoJsonType.GeometryCollection)
+ throw new IllegalArgumentException("invalid argument");
+
+ if (m_position == null && m_point == null) {
+ switch (geo_json_type)
+ {
+ case Point: {
+ if (m_num_embeddings > 1) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ geometry = new Point();
+ break;
+ }
+ case MultiPoint: {
+ if (m_num_embeddings > 2) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ geometry = new MultiPoint();
+ break;
+ }
+ case LineString: {
+ if (m_num_embeddings > 2) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ geometry = new Polyline();
+ break;
+ }
+ case MultiLineString: {
+ if (m_num_embeddings > 3) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ geometry = new Polyline();
+ break;
+ }
+ case Polygon: {
+ if (m_num_embeddings > 3) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ geometry = new Polygon();
+ break;
+ }
+ case MultiPolygon: {
+ assert (m_num_embeddings <= 4);
+ geometry = new Polygon();
+ break;
+ }
+ default:
+ throw new JsonGeometryException("parsing error");
+ }
+ } else if (m_num_embeddings == 1) {
+ if (geo_json_type != GeoJsonType.Point) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ assert (m_point != null);
+ geometry = m_point;
+ } else if (m_num_embeddings == 2) {
+ if (geo_json_type == GeoJsonType.MultiPoint) {
+ geometry = createMultiPointFromStreams_();
+ } else if (geo_json_type == GeoJsonType.LineString) {
+ geometry = createPolylineFromStreams_();
+ } else {
+ throw new JsonGeometryException("parsing error");
+ }
+ } else if (m_num_embeddings == 3) {
+ if (geo_json_type == GeoJsonType.Polygon) {
+ geometry = createPolygonFromStreams_();
+ } else if (geo_json_type == GeoJsonType.MultiLineString) {
+ geometry = createPolylineFromStreams_();
+ } else {
+ throw new JsonGeometryException("parsing error");
+ }
+ } else {
+ if (geo_json_type != GeoJsonType.MultiPolygon) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ geometry = createPolygonFromStreams_();
+ }
+
+ return geometry;
+ }
+
+ private Geometry createPolygonFromStreams_() {
+ assert (m_position != null);
+ assert (m_paths != null);
+ assert ((m_num_embeddings == 3 && m_path_flags == null) || (m_num_embeddings == 4 && m_path_flags != null));
+
+ Polygon polygon = new Polygon();
+ MultiPathImpl multi_path_impl = (MultiPathImpl) polygon._getImpl();
+
+ checkPathPointCountsForMultiPath_(true);
+ multi_path_impl.setAttributeStreamRef(Semantics.POSITION,
+ m_position);
+
+ if (m_b_has_zs) {
+ assert (m_zs != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.Z, m_zs);
+ }
+
+ if (m_b_has_ms) {
+ assert (m_ms != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.M, m_ms);
+ }
+
+ if (m_path_flags == null) {
+ m_path_flags = (AttributeStreamOfInt8) AttributeStreamBase
+ .createByteStream(m_paths.size(), (byte) 0);
+ m_path_flags
+ .setBits(
+ 0,
+ (byte) (PathFlags.enumClosed | PathFlags.enumOGCStartPolygon));
+
+ for (int i = 1; i < m_path_flags.size() - 1; i++) {
+ m_path_flags.setBits(i, (byte) PathFlags.enumClosed);
+ }
+ }
+
+ multi_path_impl.setPathStreamRef(m_paths);
+ multi_path_impl.setPathFlagsStreamRef(m_path_flags);
+ multi_path_impl
+ .notifyModified(MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
+
+ AttributeStreamOfInt8 path_flags_clone = new AttributeStreamOfInt8(
+ m_path_flags);
+
+ for (int i = 0; i < path_flags_clone.size() - 1; i++) {
+ assert ((path_flags_clone.read(i) & PathFlags.enumClosed) != 0);
+ assert ((m_path_flags.read(i) & PathFlags.enumClosed) != 0);
+
+ if ((path_flags_clone.read(i) & PathFlags.enumOGCStartPolygon) != 0) {// Should
+ // be
+ // clockwise
+ if (!InternalUtils.isClockwiseRing(multi_path_impl, i)) {
+ multi_path_impl.reversePath(i); // make clockwise
+ }
+ } else {// Should be counter-clockwise
+ if (InternalUtils.isClockwiseRing(multi_path_impl, i)) {
+ multi_path_impl.reversePath(i); // make
+ // counter-clockwise
+ }
+ }
+ }
+
+ multi_path_impl.setPathFlagsStreamRef(path_flags_clone);
+ multi_path_impl.clearDirtyOGCFlags();
+
+ return polygon;
+ }
+
+ private Geometry createPolylineFromStreams_() {
+ assert (m_position != null);
+ assert ((m_num_embeddings == 2 && m_paths == null) || (m_num_embeddings == 3 && m_paths != null));
+ assert (m_path_flags == null);
+
+ Polyline polyline = new Polyline();
+ MultiPathImpl multi_path_impl = (MultiPathImpl) polyline._getImpl();
+
+ if (m_paths == null) {
+ m_paths = (AttributeStreamOfInt32) AttributeStreamBase
+ .createIndexStream(0);
+ m_paths.add(0);
+ m_paths.add(m_position.size() / 2);
+ }
+
+ checkPathPointCountsForMultiPath_(false);
+ multi_path_impl.setAttributeStreamRef(Semantics.POSITION,
+ m_position);
+
+ if (m_b_has_zs) {
+ assert (m_zs != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.Z, m_zs);
+ }
+
+ if (m_b_has_ms) {
+ assert (m_ms != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.M, m_ms);
+ }
+
+ m_path_flags = (AttributeStreamOfInt8) AttributeStreamBase
+ .createByteStream(m_paths.size(), (byte) 0);
+
+ multi_path_impl.setPathStreamRef(m_paths);
+ multi_path_impl.setPathFlagsStreamRef(m_path_flags);
+ multi_path_impl
+ .notifyModified(MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
+
+ return polyline;
+ }
+
+ private Geometry createMultiPointFromStreams_() {
+ assert (m_position != null);
+ assert (m_paths == null);
+ assert (m_path_flags == null);
+
+ MultiPoint multi_point = new MultiPoint();
+ MultiPointImpl multi_point_impl = (MultiPointImpl) multi_point
+ ._getImpl();
+ multi_point_impl.setAttributeStreamRef(Semantics.POSITION,
+ m_position);
+
+ if (m_b_has_zs) {
+ assert (m_zs != null);
+ multi_point_impl.setAttributeStreamRef(Semantics.Z, m_zs);
+ }
+
+ if (m_b_has_ms) {
+ assert (m_ms != null);
+ multi_point_impl.setAttributeStreamRef(Semantics.M, m_ms);
+ }
+
+ multi_point_impl.resize(m_position.size() / 2);
+ multi_point_impl.notifyModified(MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
+ return multi_point;
+ }
+
+ private void checkPathPointCountsForMultiPath_(boolean b_is_polygon) {
+ Point2D pt1 = new Point2D(), pt2 = new Point2D();
+ double z1 = 0.0, z2 = 0.0, m1 = 0.0, m2 = 0.0;
+ int path_count = m_paths.size() - 1;
+ int guess_adjustment = 0;
+
+ if (b_is_polygon) {// Polygon
+ guess_adjustment = path_count; // may remove up to path_count
+ // number of points
+ } else {// Polyline
+ for (int path = 0; path < path_count; path++) {
+ int path_size = m_paths.read(path + 1) - m_paths.read(path);
+
+ if (path_size == 1) {
+ guess_adjustment--; // will add a point for each path
+ // containing only 1 point
+ }
+ }
+
+ if (guess_adjustment == 0) {
+ return; // all paths are okay
+ }
+ }
+
+ AttributeStreamOfDbl adjusted_position = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(m_position.size() - guess_adjustment);
+ AttributeStreamOfInt32 adjusted_paths = (AttributeStreamOfInt32) AttributeStreamBase
+ .createIndexStream(m_paths.size());
+ AttributeStreamOfDbl adjusted_zs = null;
+ AttributeStreamOfDbl adjusted_ms = null;
+
+ if (m_b_has_zs) {
+ adjusted_zs = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(m_zs.size() - guess_adjustment);
+ }
+
+ if (m_b_has_ms) {
+ adjusted_ms = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(m_ms.size() - guess_adjustment);
+ }
+
+ int adjusted_start = 0;
+ adjusted_paths.write(0, 0);
+
+ for (int path = 0; path < path_count; path++) {
+ int path_start = m_paths.read(path);
+ int path_end = m_paths.read(path + 1);
+ int path_size = path_end - path_start;
+ assert (path_size != 0); // we should not have added empty parts
+ // on import
+
+ if (path_size == 1) {
+ insertIntoAdjustedStreams_(adjusted_position, adjusted_zs,
+ adjusted_ms, adjusted_start, path_start, path_size);
+ insertIntoAdjustedStreams_(adjusted_position, adjusted_zs,
+ adjusted_ms, adjusted_start + 1, path_start,
+ path_size);
+ adjusted_start += 2;
+ } else if (path_size >= 3 && b_is_polygon) {
+ m_position.read(path_start * 2, pt1);
+ m_position.read((path_end - 1) * 2, pt2);
+
+ if (m_b_has_zs) {
+ z1 = m_zs.readAsDbl(path_start);
+ z2 = m_zs.readAsDbl(path_end - 1);
+ }
+
+ if (m_b_has_ms) {
+ m1 = m_ms.readAsDbl(path_start);
+ m2 = m_ms.readAsDbl(path_end - 1);
+ }
+
+ if (pt1.equals(pt2)
+ && (NumberUtils.isNaN(z1) && NumberUtils.isNaN(z2) || z1 == z2)
+ && (NumberUtils.isNaN(m1) && NumberUtils.isNaN(m2) || m1 == m2)) {
+ insertIntoAdjustedStreams_(adjusted_position,
+ adjusted_zs, adjusted_ms, adjusted_start,
+ path_start, path_size - 1);
+ adjusted_start += path_size - 1;
+ } else {
+ insertIntoAdjustedStreams_(adjusted_position,
+ adjusted_zs, adjusted_ms, adjusted_start,
+ path_start, path_size);
+ adjusted_start += path_size;
+ }
+ } else {
+ insertIntoAdjustedStreams_(adjusted_position, adjusted_zs,
+ adjusted_ms, adjusted_start, path_start, path_size);
+ adjusted_start += path_size;
+ }
+ adjusted_paths.write(path + 1, adjusted_start);
+ }
+
+ m_position = adjusted_position;
+ m_paths = adjusted_paths;
+ m_zs = adjusted_zs;
+ m_ms = adjusted_ms;
+ }
+
+ private void insertIntoAdjustedStreams_(
+ AttributeStreamOfDbl adjusted_position,
+ AttributeStreamOfDbl adjusted_zs,
+ AttributeStreamOfDbl adjusted_ms, int adjusted_start,
+ int path_start, int count) {
+ adjusted_position.insertRange(adjusted_start * 2, m_position,
+ path_start * 2, count * 2, true, 2, adjusted_start * 2);
+
+ if (m_b_has_zs) {
+ adjusted_zs.insertRange(adjusted_start, m_zs, path_start,
+ count, true, 1, adjusted_start);
+ }
+
+ if (m_b_has_ms) {
+ adjusted_ms.insertRange(adjusted_start, m_ms, path_start,
+ count, true, 1, adjusted_start);
+ }
+ }
+
+ static SpatialReference importSpatialReferenceFromCrs(
+ JsonReader json_iterator, ProgressTracker progress_tracker)
+ throws JsonGeometryException {
+ // According to the spec, a null crs corresponds to no spatial
+ // reference
+ if (json_iterator.currentToken() == JsonReader.Token.VALUE_NULL) {
+ return null;
+ }
+
+ if (json_iterator.currentToken() == JsonReader.Token.VALUE_STRING) {// see
+ // http://wiki.geojson.org/RFC-001
+ // (this
+ // is
+ // deprecated,
+ // but
+ // there
+ // may
+ // be
+ // data
+ // with
+ // this
+ // format)
+
+ String crs_short_form = json_iterator.currentString();
+ int wkid = GeoJsonCrsTables
+ .getWkidFromCrsShortForm(crs_short_form);
+
+ if (wkid == -1) {
+ throw new GeometryException("not implemented");
+ }
+
+ SpatialReference spatial_reference = null;
+
+ try {
+ spatial_reference = SpatialReference.create(wkid);
+ } catch (Exception e) {
+ }
+
+ return spatial_reference;
+ }
+
+ if (json_iterator.currentToken() != JsonReader.Token.START_OBJECT) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ // This is to support all cases of crs identifiers I've seen. Some
+ // may be rare or are legacy formats, but all are simple to
+ // accomodate.
+ boolean b_found_type = false;
+ boolean b_found_properties = false;
+ boolean b_found_properties_name = false;
+ boolean b_found_properties_href = false;
+ boolean b_found_properties_urn = false;
+ boolean b_found_properties_url = false;
+ boolean b_found_properties_code = false;
+ boolean b_found_esriwkt = false;
+ String crs_field = null;
+ String properties_field = null;
+ String crs_identifier_name = null;
+ String crs_identifier_urn = null;
+ String crs_identifier_href = null;
+ String crs_identifier_url = null;
+ String esriwkt = null;
+ int crs_identifier_code = -1;
+ JsonReader.Token current_token;
+
+ while (json_iterator.nextToken() != JsonReader.Token.END_OBJECT) {
+ crs_field = json_iterator.currentString();
+
+ if (crs_field.equals("type")) {
+ if (b_found_type) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_type = true;
+
+ current_token = json_iterator.nextToken();
+
+ if (current_token != JsonReader.Token.VALUE_STRING) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ //type = json_iterator.currentString();
+ } else if (crs_field.equals("properties")) {
+ if (b_found_properties) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_properties = true;
+
+ current_token = json_iterator.nextToken();
+
+ if (current_token != JsonReader.Token.START_OBJECT) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ while (json_iterator.nextToken() != JsonReader.Token.END_OBJECT) {
+ properties_field = json_iterator.currentString();
+
+ if (properties_field.equals("name")) {
+ if (b_found_properties_name) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_properties_name = true;
+ crs_identifier_name = getCrsIdentifier_(json_iterator);
+ } else if (properties_field.equals("href")) {
+ if (b_found_properties_href) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_properties_href = true;
+ crs_identifier_href = getCrsIdentifier_(json_iterator);
+ } else if (properties_field.equals("urn")) {
+ if (b_found_properties_urn) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_properties_urn = true;
+ crs_identifier_urn = getCrsIdentifier_(json_iterator);
+ } else if (properties_field.equals("url")) {
+ if (b_found_properties_url) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_properties_url = true;
+ crs_identifier_url = getCrsIdentifier_(json_iterator);
+ } else if (properties_field.equals("code")) {
+ if (b_found_properties_code) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_properties_code = true;
+
+ current_token = json_iterator.nextToken();
+
+ if (current_token != JsonReader.Token.VALUE_NUMBER_INT) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ crs_identifier_code = json_iterator
+ .currentIntValue();
+ } else {
+ json_iterator.nextToken();
+ json_iterator.skipChildren();
+ }
+ }
+ } else if (crs_field.equals("esriwkt")) {
+ if (b_found_esriwkt) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ b_found_esriwkt = true;
+
+ current_token = json_iterator.nextToken();
+
+ if (current_token != JsonReader.Token.VALUE_STRING) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ esriwkt = json_iterator.currentString();
+ } else {
+ json_iterator.nextToken();
+ json_iterator.skipChildren();
+ }
+ }
+
+ if ((!b_found_type || !b_found_properties) && !b_found_esriwkt) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ int wkid = -1;
+
+ if (b_found_properties_name) {
+ wkid = GeoJsonCrsTables.getWkidFromCrsName(crs_identifier_name); // see
+ // http://wiki.geojson.org/GeoJSON_draft_version_6
+ // (most
+ // common)
+ } else if (b_found_properties_href) {
+ wkid = GeoJsonCrsTables.getWkidFromCrsHref(crs_identifier_href); // see
+ // http://wiki.geojson.org/GeoJSON_draft_version_6
+ // (somewhat
+ // common)
+ } else if (b_found_properties_urn) {
+ wkid = GeoJsonCrsTables
+ .getWkidFromCrsOgcUrn(crs_identifier_urn); // see
+ // http://wiki.geojson.org/GeoJSON_draft_version_5
+ // (rare)
+ } else if (b_found_properties_url) {
+ wkid = GeoJsonCrsTables.getWkidFromCrsHref(crs_identifier_url); // see
+ // http://wiki.geojson.org/GeoJSON_draft_version_5
+ // (rare)
+ } else if (b_found_properties_code) {
+ wkid = crs_identifier_code; // see
+ // http://wiki.geojson.org/GeoJSON_draft_version_5
+ // (rare)
+ } else if (!b_found_esriwkt) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ if (wkid < 0 && !b_found_esriwkt && !b_found_properties_name) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ SpatialReference spatial_reference = null;
+
+ if (wkid > 0) {
+ try {
+ spatial_reference = SpatialReference.create(wkid);
+ } catch (Exception e) {
+ }
+ }
+
+ if (spatial_reference == null) {
+ try {
+ if (b_found_esriwkt) {// I exported crs wkt strings like
+ // this
+ spatial_reference = SpatialReference.create(esriwkt);
+ } else if (b_found_properties_name) {// AGOL exported crs
+ // wkt strings like
+ // this where the
+ // crs identifier of
+ // the properties
+ // name is like
+ // "ESRI:"
+ String potential_wkt = GeoJsonCrsTables
+ .getWktFromCrsName(crs_identifier_name);
+ spatial_reference = SpatialReference
+ .create(potential_wkt);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ return spatial_reference;
+ }
+
+ // see http://geojsonwg.github.io/draft-geojson/draft.html
+ static SpatialReference importSpatialReferenceFromCrsUrn_(
+ JsonReader json_iterator, ProgressTracker progress_tracker)
+ throws JsonGeometryException {
+ // According to the spec, a null crs corresponds to no spatial
+ // reference
+ if (json_iterator.currentToken() == JsonReader.Token.VALUE_NULL) {
+ return null;
+ }
+
+ if (json_iterator.currentToken() != JsonReader.Token.VALUE_STRING) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ String crs_identifier_urn = json_iterator.currentString();
+
+ int wkid = GeoJsonCrsTables.getWkidFromCrsName(crs_identifier_urn); // This
+ // will
+ // check
+ // for
+ // short
+ // form
+ // name,
+ // as
+ // well
+ // as
+ // long
+ // form
+ // URNs
+
+ if (wkid == -1) {
+ throw new GeometryException("not implemented");
+ }
+
+ SpatialReference spatial_reference = SpatialReference.create(wkid);
+
+ return spatial_reference;
+ }
+
+ private static String getCrsIdentifier_(JsonReader json_iterator)
+ throws JsonGeometryException {
+ JsonReader.Token current_token = json_iterator.nextToken();
+
+ if (current_token != JsonReader.Token.VALUE_STRING) {
+ throw new JsonGeometryException("parsing error");
+ }
+
+ return json_iterator.currentString();
+ }
+
+ }
+
+ @Override
+ public MapOGCStructure executeOGC(int import_flags, String geoJsonString,
+ ProgressTracker progress_tracker) throws JsonGeometryException {
+ return executeOGC(import_flags, JsonParserReader.createFromString(geoJsonString),
+ progress_tracker);
+ }
+
+ public MapOGCStructure executeOGC(int import_flags,
+ JsonReader json_iterator, ProgressTracker progress_tracker)
+ throws JsonGeometryException {
+ MapOGCStructure mapOGCStructure = OperatorImportFromGeoJsonHelper.importFromGeoJson(
+ import_flags, Geometry.Type.Unknown, json_iterator,
+ progress_tracker, false, 0);
+
+ //This is to restore legacy behavior when we always return a geometry collection of one element.
+ MapOGCStructure res = new MapOGCStructure();
+ res.m_ogcStructure = new OGCStructure();
+ res.m_ogcStructure.m_type = 0;
+ res.m_ogcStructure.m_structures = new ArrayList();
+ res.m_ogcStructure.m_structures.add(mapOGCStructure.m_ogcStructure);
+ res.m_spatialReference = mapOGCStructure.m_spatialReference;
+ return res;
+ }
+
+}
diff --git a/src/com/esri/core/geometry/OperatorImportFromJson.java b/src/main/java/com/esri/core/geometry/OperatorImportFromJson.java
similarity index 84%
rename from src/com/esri/core/geometry/OperatorImportFromJson.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromJson.java
index 66e59b9b..93f30da5 100644
--- a/src/com/esri/core/geometry/OperatorImportFromJson.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromJson.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,13 +24,6 @@
package com.esri.core.geometry;
-import java.io.IOException;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-
-import com.esri.core.geometry.Operator.Type;
-
/**
*Import from JSON format.
*/
@@ -46,22 +39,20 @@ public Type getType() {
* @return Returns a MapGeometryCursor.
*/
abstract MapGeometryCursor execute(Geometry.Type type,
- JsonParserCursor jsonParserCursor);
+ JsonReaderCursor jsonReaderCursor);
/**
*Performs the ImportFromJson operation on a single Json string
*@return Returns a MapGeometry.
*/
public abstract MapGeometry execute(Geometry.Type type,
- JsonParser jsonParser);
+ JsonReader jsonReader);
/**
*Performs the ImportFromJson operation on a single Json string
*@return Returns a MapGeometry.
*/
- public abstract MapGeometry execute(Geometry.Type type, String string)
- throws JsonParseException, IOException;
-
+ public abstract MapGeometry execute(Geometry.Type type, String string);
public static OperatorImportFromJson local() {
return (OperatorImportFromJson) OperatorFactoryLocal.getInstance()
diff --git a/src/com/esri/core/geometry/OperatorImportFromJsonCursor.java b/src/main/java/com/esri/core/geometry/OperatorImportFromJsonCursor.java
similarity index 85%
rename from src/com/esri/core/geometry/OperatorImportFromJsonCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromJsonCursor.java
index ac982316..2971f441 100644
--- a/src/com/esri/core/geometry/OperatorImportFromJsonCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromJsonCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,19 +26,15 @@
import com.esri.core.geometry.MultiVertexGeometryImpl.DirtyFlags;
import com.esri.core.geometry.VertexDescription.Semantics;
-import java.io.IOException;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
class OperatorImportFromJsonCursor extends MapGeometryCursor {
- JsonParserCursor m_inputJsonParsers;
+ JsonReaderCursor m_inputJsonParsers;
int m_type;
int m_index;
- public OperatorImportFromJsonCursor(int type, JsonParserCursor jsonParsers) {
+ public OperatorImportFromJsonCursor(int type, JsonReaderCursor jsonParsers) {
m_index = -1;
if (jsonParsers == null)
throw new IllegalArgumentException();
@@ -54,7 +50,7 @@ public int getGeometryID() {
@Override
public MapGeometry next() {
- JsonParser jsonParser;
+ JsonReader jsonParser;
if ((jsonParser = m_inputJsonParsers.next()) != null) {
m_index = m_inputJsonParsers.getID();
return importFromJsonParser(m_type, jsonParser);
@@ -62,7 +58,7 @@ public MapGeometry next() {
return null;
}
- private static MapGeometry importFromJsonParser(int gt, JsonParser parser) {
+ static MapGeometry importFromJsonParser(int gt, JsonReader parser) {
MapGeometry mp;
try {
@@ -109,26 +105,26 @@ private static MapGeometry importFromJsonParser(int gt, JsonParser parser) {
Geometry geometry = null;
SpatialReference spatial_reference = null;
- while (parser.nextToken() != JsonToken.END_OBJECT) {
- String name = parser.getCurrentName();
+ while (parser.nextToken() != JsonReader.Token.END_OBJECT) {
+ String name = parser.currentString();
parser.nextToken();
if (!bFoundSpatial_reference && name.equals("spatialReference")) {
bFoundSpatial_reference = true;
- if (parser.getCurrentToken() == JsonToken.START_OBJECT) {
+ if (parser.currentToken() == JsonReader.Token.START_OBJECT) {
spatial_reference = SpatialReference.fromJson(parser);
} else {
- if (parser.getCurrentToken() != JsonToken.VALUE_NULL)
+ if (parser.currentToken() != JsonReader.Token.VALUE_NULL)
throw new GeometryException(
"failed to parse spatial reference: object or null is expected");
}
} else if (!bFoundHasZ && name.equals("hasZ")) {
bFoundHasZ = true;
- bHasZ = (parser.getCurrentToken() == JsonToken.VALUE_TRUE);
+ bHasZ = (parser.currentToken() == JsonReader.Token.VALUE_TRUE);
} else if (!bFoundHasM && name.equals("hasM")) {
bFoundHasM = true;
- bHasM = (parser.getCurrentToken() == JsonToken.VALUE_TRUE);
+ bHasM = (parser.currentToken() == JsonReader.Token.VALUE_TRUE);
} else if (!bFoundPolygon
&& name.equals("rings")
&& (gt == Geometry.GeometryType.Unknown || gt == Geometry.GeometryType.Polygon)) {
@@ -272,62 +268,59 @@ private static MapGeometry importFromJsonParser(int gt, JsonParser parser) {
mp = new MapGeometry(geometry, spatial_reference);
} catch (Exception e) {
- e.printStackTrace();
return null;
}
return mp;
}
- public static MapGeometry fromJsonToUnknown(JsonParser parser)
+ public static MapGeometry fromJsonToUnknown(JsonReader parser)
throws Exception {
return importFromJsonParser(Geometry.GeometryType.Unknown, parser);
}
- public static MapGeometry fromJsonToEnvelope(JsonParser parser)
+ public static MapGeometry fromJsonToEnvelope(JsonReader parser)
throws Exception {
return importFromJsonParser(Geometry.GeometryType.Envelope, parser);
}
- public static MapGeometry fromJsonToPoint(JsonParser parser)
+ public static MapGeometry fromJsonToPoint(JsonReader parser)
throws Exception {
return importFromJsonParser(Geometry.GeometryType.Point, parser);
}
- public static MapGeometry fromJsonToPolygon(JsonParser parser)
+ public static MapGeometry fromJsonToPolygon(JsonReader parser)
throws Exception {
return importFromJsonParser(Geometry.GeometryType.Polygon, parser);
}
- public static MapGeometry fromJsonToPolyline(JsonParser parser)
+ public static MapGeometry fromJsonToPolyline(JsonReader parser)
throws Exception {
return importFromJsonParser(Geometry.GeometryType.Polyline, parser);
}
- public static MapGeometry fromJsonToMultiPoint(JsonParser parser)
+ public static MapGeometry fromJsonToMultiPoint(JsonReader parser)
throws Exception {
return importFromJsonParser(Geometry.GeometryType.MultiPoint, parser);
}
- private static void windup(JsonParser parser) throws IOException,
- JsonParseException {
+ private static void windup(JsonReader parser) {
parser.skipChildren();
}
- private static double readDouble(JsonParser parser) throws IOException,
- JsonParseException {
- if (parser.getCurrentToken() == JsonToken.VALUE_NULL
- || parser.getCurrentToken() == JsonToken.VALUE_STRING
- && parser.getCurrentName().equals("NaN"))
+ private static double readDouble(JsonReader parser) {
+ if (parser.currentToken() == JsonReader.Token.VALUE_NULL
+ || parser.currentToken() == JsonReader.Token.VALUE_STRING
+ && parser.currentString().equals("NaN"))
return NumberUtils.NaN();
else
- return parser.getValueAsDouble();
+ return parser.currentDoubleValue();
}
- private static Geometry importFromJsonMultiPoint(JsonParser parser,
+ private static Geometry importFromJsonMultiPoint(JsonReader parser,
AttributeStreamOfDbl as, AttributeStreamOfDbl bs) throws Exception {
- if (parser.getCurrentToken() != JsonToken.START_ARRAY)
+ if (parser.currentToken() != JsonReader.Token.START_ARRAY)
throw new GeometryException(
"failed to parse multipoint: array of vertices is expected");
@@ -342,13 +335,13 @@ private static Geometry importFromJsonMultiPoint(JsonParser parser,
// At start of rings
int sz;
double[] buf = new double[4];
- while (parser.nextToken() != JsonToken.END_ARRAY) {
- if (parser.getCurrentToken() != JsonToken.START_ARRAY)
+ while (parser.nextToken() != JsonReader.Token.END_ARRAY) {
+ if (parser.currentToken() != JsonReader.Token.START_ARRAY)
throw new GeometryException(
"failed to parse multipoint: array is expected, multipoint vertices consist of arrays of cooridinates");
sz = 0;
- while (parser.nextToken() != JsonToken.END_ARRAY) {
+ while (parser.nextToken() != JsonReader.Token.END_ARRAY) {
buf[sz++] = readDouble(parser);
}
@@ -408,9 +401,9 @@ else if (c < 16)
}
private static Geometry importFromJsonMultiPath(boolean b_polygon,
- JsonParser parser, AttributeStreamOfDbl as, AttributeStreamOfDbl bs)
+ JsonReader parser, AttributeStreamOfDbl as, AttributeStreamOfDbl bs)
throws Exception {
- if (parser.getCurrentToken() != JsonToken.START_ARRAY)
+ if (parser.currentToken() != JsonReader.Token.START_ARRAY)
throw new GeometryException(
"failed to parse multipath: array of array of vertices is expected");
@@ -438,8 +431,8 @@ private static Geometry importFromJsonMultiPath(boolean b_polygon,
int requiredSize = b_polygon ? 3 : 2;
// At start of rings
- while (parser.nextToken() != JsonToken.END_ARRAY) {
- if (parser.getCurrentToken() != JsonToken.START_ARRAY)
+ while (parser.nextToken() != JsonReader.Token.END_ARRAY) {
+ if (parser.currentToken() != JsonReader.Token.START_ARRAY)
throw new GeometryException(
"failed to parse multipath: ring/path array is expected");
@@ -449,13 +442,13 @@ private static Geometry importFromJsonMultiPath(boolean b_polygon,
int szstart = 0;
parser.nextToken();
- while (parser.getCurrentToken() != JsonToken.END_ARRAY) {
- if (parser.getCurrentToken() != JsonToken.START_ARRAY)
+ while (parser.currentToken() != JsonReader.Token.END_ARRAY) {
+ if (parser.currentToken() != JsonReader.Token.START_ARRAY)
throw new GeometryException(
"failed to parse multipath: array is expected, rings/paths vertices consist of arrays of cooridinates");
sz = 0;
- while (parser.nextToken() != JsonToken.END_ARRAY) {
+ while (parser.nextToken() != JsonReader.Token.END_ARRAY) {
buf[sz++] = readDouble(parser);
}
@@ -524,7 +517,7 @@ else if (c < 16)
point_count++;
pathPointCount++;
} while (pathPointCount < requiredSize
- && parser.getCurrentToken() == JsonToken.END_ARRAY);
+ && parser.currentToken() == JsonReader.Token.END_ARRAY);
}
if (b_polygon && pathPointCount > requiredSize && sz == szstart
diff --git a/src/main/java/com/esri/core/geometry/OperatorImportFromJsonLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromJsonLocal.java
new file mode 100644
index 00000000..55d94171
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromJsonLocal.java
@@ -0,0 +1,42 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+class OperatorImportFromJsonLocal extends OperatorImportFromJson {
+
+ @Override
+ public MapGeometryCursor execute(Geometry.Type type,
+ JsonReaderCursor jsonParserCursor) {
+ return new OperatorImportFromJsonCursor(type.value(), jsonParserCursor);
+ }
+
+ @Override
+ public MapGeometry execute(Geometry.Type type, JsonReader jsonParser) {
+ return OperatorImportFromJsonCursor.importFromJsonParser(type.value(), jsonParser);
+ }
+ @Override
+ public MapGeometry execute(Geometry.Type type, String string) {
+ return execute(type, JsonParserReader.createFromString(string));
+ }
+}
diff --git a/src/com/esri/core/geometry/OperatorImportFromWkb.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWkb.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorImportFromWkb.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromWkb.java
index 9550e4cf..a80e3bd9 100644
--- a/src/com/esri/core/geometry/OperatorImportFromWkb.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromWkb.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorImportFromWkbLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWkbLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorImportFromWkbLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromWkbLocal.java
index c5ee10aa..1fa9685c 100644
--- a/src/com/esri/core/geometry/OperatorImportFromWkbLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromWkbLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -692,8 +692,22 @@ private static Geometry importFromWkbPolygon(boolean bMultiPolygon,
polygon.notifyModified(MultiPathImpl.DirtyFlags.DirtyAll);
- if (!InternalUtils.isClockwiseRing(polygon, 0))
- polygon.reverseAllPaths();
+ AttributeStreamOfInt8 path_flags_clone = new AttributeStreamOfInt8(
+ pathFlags);
+
+ for (int i = 0; i < path_flags_clone.size() - 1; i++) {
+ if (((int) path_flags_clone.read(i) & (int) PathFlags.enumOGCStartPolygon) != 0) {// Should
+ // be
+ // clockwise
+ if (!InternalUtils.isClockwiseRing(polygon, i))
+ polygon.reversePath(i); // make clockwise
+ } else {// Should be counter-clockwise
+ if (InternalUtils.isClockwiseRing(polygon, i))
+ polygon.reversePath(i); // make counter-clockwise
+ }
+ }
+
+ polygon.setPathFlagsStreamRef(path_flags_clone);
}
if ((importFlags & (int) WkbImportFlags.wkbImportNonTrusted) == 0)
diff --git a/src/com/esri/core/geometry/OperatorImportFromWkt.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWkt.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorImportFromWkt.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromWkt.java
index b64c70ac..60b0460d 100644
--- a/src/com/esri/core/geometry/OperatorImportFromWkt.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromWkt.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorImportFromWktLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWktLocal.java
similarity index 96%
rename from src/com/esri/core/geometry/OperatorImportFromWktLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorImportFromWktLocal.java
index d742caa9..3b6a74f0 100644
--- a/src/com/esri/core/geometry/OperatorImportFromWktLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromWktLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -196,8 +196,23 @@ static Geometry polygonTaggedText(boolean b_multi_polygon,
multi_path_impl.notifyModified(MultiPathImpl.DirtyFlags.DirtyAll);
- if (!InternalUtils.isClockwiseRing(multi_path_impl, 0))
- multi_path_impl.reverseAllPaths();
+ AttributeStreamOfInt8 path_flags_clone = new AttributeStreamOfInt8(
+ path_flags);
+
+ for (int i = 0; i < path_flags_clone.size() - 1; i++) {
+ if (((int) path_flags_clone.read(i) & (int) PathFlags.enumOGCStartPolygon) != 0) {// Should
+ // be
+ // clockwise
+ if (!InternalUtils.isClockwiseRing(multi_path_impl, i))
+ multi_path_impl.reversePath(i); // make clockwise
+ } else {// Should be counter-clockwise
+ if (InternalUtils.isClockwiseRing(multi_path_impl, i))
+ multi_path_impl.reversePath(i); // make
+ // counter-clockwise
+ }
+ }
+
+ multi_path_impl.setPathFlagsStreamRef(path_flags_clone);
}
if ((import_flags & (int) WktImportFlags.wktImportNonTrusted) == 0)
diff --git a/src/com/esri/core/geometry/OperatorInternalRelationUtils.java b/src/main/java/com/esri/core/geometry/OperatorInternalRelationUtils.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorInternalRelationUtils.java
rename to src/main/java/com/esri/core/geometry/OperatorInternalRelationUtils.java
index cc7fa41d..5c61ad20 100644
--- a/src/com/esri/core/geometry/OperatorInternalRelationUtils.java
+++ b/src/main/java/com/esri/core/geometry/OperatorInternalRelationUtils.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -88,7 +88,7 @@ public static int quickTest2D(Geometry geomA, Geometry geomB,
return reverseResult(quickTest2DPolygonPoint((Polygon) geomB,
(Point) geomA, tolerance));
}
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);//what
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);//what
// else?
}
case Geometry.GeometryType.Envelope: {
@@ -110,7 +110,7 @@ public static int quickTest2D(Geometry geomA, Geometry geomB,
return reverseResult(quickTest2DPolygonEnvelope(
(Polygon) geomB, (Envelope) geomA, tolerance));
}
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);//what
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);//what
// else?
}
case Geometry.GeometryType.MultiPoint: {
@@ -131,7 +131,7 @@ public static int quickTest2D(Geometry geomA, Geometry geomB,
return reverseResult(quickTest2DPolygonMultiPoint(
(Polygon) geomB, (MultiPoint) geomA, tolerance));
}
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);//what
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);//what
// else?
}
case Geometry.GeometryType.Polyline: {
@@ -152,7 +152,7 @@ public static int quickTest2D(Geometry geomA, Geometry geomB,
return reverseResult(quickTest2DPolygonPolyline(
(Polygon) geomB, (Polyline) geomA, tolerance));
}
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);//what
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);//what
// else?
}
case Geometry.GeometryType.Polygon: {
@@ -173,12 +173,12 @@ public static int quickTest2D(Geometry geomA, Geometry geomB,
return quickTest2DPolygonPolygon((Polygon) geomA,
(Polygon) geomB, tolerance);
}
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);//what
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);//what
// else?
}
default:
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);//what
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);//what
// else?
// return 0;
}
@@ -581,7 +581,7 @@ private static int quickTest2DPolygonPoint(Polygon geomA, Point2D ptB,
if (pipres == PolygonUtils.PiPResult.PiPBoundary)
return (int) Relation.Touches;// clementini's touches
- throw new GeometryException("internal error");// GEOMTHROW(internal_error);
+ throw GeometryException.GeometryInternalError();// GEOMTHROW(internal_error);
// //what else
// return 0;
}
diff --git a/src/com/esri/core/geometry/OperatorIntersection.java b/src/main/java/com/esri/core/geometry/OperatorIntersection.java
similarity index 81%
rename from src/com/esri/core/geometry/OperatorIntersection.java
rename to src/main/java/com/esri/core/geometry/OperatorIntersection.java
index f69c86ec..5afc6e37 100644
--- a/src/com/esri/core/geometry/OperatorIntersection.java
+++ b/src/main/java/com/esri/core/geometry/OperatorIntersection.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
/**
*Intersection of geometries by a given geometry.
*/
-public abstract class OperatorIntersection extends Operator {
+public abstract class OperatorIntersection extends Operator implements CombineOperator {
@Override
public Type getType() {
return Type.Intersection;
@@ -53,14 +53,14 @@ public abstract GeometryCursor execute(GeometryCursor inputGeometries,
*@param sr The spatial reference is used to get tolerance value. Can be null, then the tolerance is not used and the operation is performed with
*a small tolerance value just enough to make the operation robust.
*@param progress_tracker Allows to cancel the operation. Can be null.
- *@param dimensionMask The dimension of the intersection. The value is either -1, or a bitmask mask of values (1 << dim).
+ *@param dimensionMask The dimension of the intersection. The value is either -1, or a bitmask mask of values (1 << dim).
*The value of -1 means the lower dimension in the intersecting pair.
*This is a fastest option when intersecting polygons with polygons or polylines.
- *The bitmask of values (1 << dim), where dim is the desired dimension value, is used to indicate
+ *The bitmask of values (1 << dim), where dim is the desired dimension value, is used to indicate
*what dimensions of geometry one wants to be returned. For example, to return
- *multipoints and lines only, pass (1 << 0) | (1 << 1), which is equivalen to 1 | 2, or 3.
- *\return Returns the cursor of the intersection result. The cursors' get_geometry_ID method returns the current ID of the input geometry
- *being processed. Wh dimensionMask is a bitmask, there will be n result geometries per one input geometry returned, where n is the number
+ *multipoints and lines only, pass (1 << 0) | (1 << 1), which is equivalen to 1 | 2, or 3.
+ *@return Returns the cursor of the intersection result. The cursors' getGeometryID method returns the current ID of the input geometry
+ *being processed. When dimensionMask is a bitmask, there will be n result geometries per one input geometry returned, where n is the number
*of bits set in the bitmask. For example, if the dimensionMask is 5, there will be two geometries per one input geometry.
*
*The operator intersects every geometry in the input_geometries with the first geometry of the intersector and returns the result.
@@ -68,7 +68,7 @@ public abstract GeometryCursor execute(GeometryCursor inputGeometries,
*Note, when the dimensionMask is -1, then for each intersected pair of geometries,
*the result has the lower of dimentions of the two geometries. That is, the dimension of the Polyline/Polyline intersection
*is always 1 (that is, for polylines it never returns crossing points, but the overlaps only).
- *If dimensionMask is 7, the operation will return any possible
+ *If dimensionMask is 7, the operation will return any possible intersections.
*/
public abstract GeometryCursor execute(GeometryCursor input_geometries,
GeometryCursor intersector, SpatialReference sr,
@@ -81,9 +81,10 @@ public abstract GeometryCursor execute(GeometryCursor input_geometries,
*points, but the overlaps only).
*The call is equivalent to calling the overloaded method using cursors:
*execute(new SimpleGeometryCursor(input_geometry), new SimpleGeometryCursor(intersector), sr, progress_tracker, mask).next();
- *where mask can be either -1 or min(1 << input_geometry.getDimension(), 1 << intersector.getDimension());
+ *where mask can be either -1 or min(1 << input_geometry.getDimension(), 1 << intersector.getDimension());
*@param inputGeometry is the Geometry instance to be intersected by the intersector.
*@param intersector is the intersector Geometry.
+ *@param sr The spatial reference to get the tolerance value from. Can be null, then the tolerance is calculated from the input geometries.
*@return Returns the intersected Geometry.
*/
public abstract Geometry execute(Geometry inputGeometry,
diff --git a/src/com/esri/core/geometry/OperatorIntersectionCursor.java b/src/main/java/com/esri/core/geometry/OperatorIntersectionCursor.java
similarity index 96%
rename from src/com/esri/core/geometry/OperatorIntersectionCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorIntersectionCursor.java
index 3d07cc5a..edcf0313 100644
--- a/src/com/esri/core/geometry/OperatorIntersectionCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorIntersectionCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -118,16 +118,16 @@ Geometry intersect(Geometry input_geom) {
// m_geomIntersector, m_spatial_reference, m_progress_tracker);
// Preprocess geometries to be clipped to the extent of intersection to
// get rid of extra segments.
- double tol = 0;
+ double t = InternalUtils.calculateToleranceFromGeometry(m_spatial_reference, commonExtent, true);
Envelope2D env = new Envelope2D();
m_geomIntersector.queryEnvelope2D(env);
Envelope2D env1 = new Envelope2D();
input_geom.queryEnvelope2D(env1);
+ env.inflate(2.0 * t, 2.0 * t);
env.intersect(env1);
assert (!env.isEmpty());
- double t = InternalUtils.calculateToleranceFromGeometry(
- m_spatial_reference, commonExtent, true) * 10;
- env.inflate(10 * t, 10 * t);
+ env.inflate(100 * t, 100 * t);
+ double tol = 0;
Geometry clippedIntersector = Clipper.clip(m_geomIntersector, env, tol,
0.0);
Geometry clippedInputGeom = Clipper.clip(input_geom, env, tol, 0.0);
@@ -191,18 +191,21 @@ GeometryCursor intersectEx(Geometry input_geom) {
Envelope2D commonExtent = InternalUtils.getMergedExtent(
m_geomIntersector, input_geom);
+ double t = InternalUtils.calculateToleranceFromGeometry(
+ m_spatial_reference, commonExtent, true);
+
// Preprocess geometries to be clipped to the extent of intersection to
// get rid of extra segments.
- double tol = 0;
+
Envelope2D env = new Envelope2D();
m_geomIntersector.queryEnvelope2D(env);
+ env.inflate(2 * t, 2 * t);
Envelope2D env1 = new Envelope2D();
input_geom.queryEnvelope2D(env1);
env.intersect(env1);
assert (!env.isEmpty());
- double t = InternalUtils.calculateToleranceFromGeometry(
- m_spatial_reference, commonExtent, true) * 10;
- env.inflate(10 * t, 10 * t);
+ env.inflate(100 * t, 100 * t);
+ double tol = 0;
Geometry clippedIntersector = Clipper.clip(m_geomIntersector, env, tol,
0.0);
Geometry clippedInputGeom = Clipper.clip(input_geom, env, tol, 0.0);
@@ -252,6 +255,7 @@ Geometry tryNativeImplementation_(Geometry input_geom) {
input_geom.queryEnvelope2D(env2D1);
Envelope2D env2D2 = new Envelope2D();
m_geomIntersector.queryEnvelope2D(env2D2);
+ env2D2.inflate(2.0 * tolerance, 2.0 * tolerance);
bResultIsEmpty = !env2D1.isIntersecting(env2D2);
}
@@ -369,7 +373,7 @@ else if (dim1 == 0) {
if (m_geomIntersectorType == Geometry.GeometryType.Point)
return TopologicalOperations.intersection(
(Point) m_geomIntersector, input_geom, tolerance1);
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
// Try Polyline vs Polygon
@@ -402,6 +406,7 @@ Geometry tryFastIntersectPolylinePolygon_(Polyline polyline, Polygon polygon) {
polygonImpl.queryEnvelope2D(clipEnvelope);
Envelope2D env1 = new Envelope2D();
polylineImpl.queryEnvelope2D(env1);
+ env1.inflate(2.0 * tolerance, 2.0 * tolerance);
clipEnvelope.intersect(env1);
assert (!clipEnvelope.isEmpty());
}
@@ -453,6 +458,7 @@ Geometry tryFastIntersectPolylinePolygon_(Polyline polyline, Polygon polygon) {
polygon = (Polygon) clippedPolygon;
polygonImpl = (MultiPathImpl) polygon._getImpl();
+ accel = polygonImpl._getAccelerators();//update accelerators
}
if (unresolvedSegments < 0) {
@@ -483,18 +489,7 @@ Geometry tryFastIntersectPolylinePolygon_(Polyline polyline, Polygon polygon) {
polygonQuadTree = accel.getQuadTree();
if (polygonQuadTree == null && polygonImpl.getPointCount() > 20) {
- Envelope2D env = new Envelope2D();
- polygon.queryEnvelope2D(env);
- QuadTreeImpl polygonQuadTreeNew = new QuadTreeImpl(env, 8);
- while (polygonIter.nextPath()) {
- while (polygonIter.hasNextSegment()) {
- Segment seg = polygonIter.nextSegment();
- seg.queryEnvelope2D(env);
- polygonQuadTreeNew.insert(polygonIter.getStartPointIndex(),
- env);
- }
- }
- polygonQuadTree = polygonQuadTreeNew;
+ polygonQuadTree = InternalUtils.buildQuadTree(polygonImpl);
}
Polyline result_polyline = (Polyline) polyline.createInstance();
@@ -611,13 +606,13 @@ Geometry tryFastIntersectPolylinePolygon_(Polyline polyline, Polygon polygon) {
resSeg.getStartXY(), tolerance) != 1) {
if (analyseClipSegment_(polygon, resSeg,
tolerance) != 1) {
- assert (false);// something went wrong.
- return null;
+ return null; //someting went wrong we'll falback to slower but robust planesweep code.
}
}
resultPolylineImpl.addSegment(resSeg, false);
state = stateAddSegment;
+ inCount = 0;
} else {
status = analyseClipSegment_(polygon, resSeg,
tolerance);
@@ -671,9 +666,7 @@ Geometry tryFastIntersectPolylinePolygon_(Polyline polyline, Polygon polygon) {
// be
// inside.
if (clipStatus < 0) {
- assert (clipStatus >= 0);// E-mail the repro case to
- // the Geometry team to
- // investigate.
+ assert (clipStatus >= 0);
return null;// something goes wrong, resort to
// planesweep
}
diff --git a/src/com/esri/core/geometry/OperatorIntersectionLocal.java b/src/main/java/com/esri/core/geometry/OperatorIntersectionLocal.java
similarity index 94%
rename from src/com/esri/core/geometry/OperatorIntersectionLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorIntersectionLocal.java
index f9adfbca..71d2d9e6 100644
--- a/src/com/esri/core/geometry/OperatorIntersectionLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorIntersectionLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -65,8 +65,7 @@ public boolean accelerateGeometry(Geometry geometry,
if (!canAccelerateGeometry(geometry))
return false;
- double tol = spatialReference != null ? spatialReference
- .getTolerance(VertexDescription.Semantics.POSITION) : 0;
+ double tol = InternalUtils.calculateToleranceFromGeometry(spatialReference, geometry, false);
boolean accelerated = ((MultiVertexGeometryImpl) geometry._getImpl())
._buildQuadTreeAccelerator(accelDegree);
accelerated |= ((MultiVertexGeometryImpl) geometry._getImpl())
diff --git a/src/com/esri/core/geometry/OperatorIntersects.java b/src/main/java/com/esri/core/geometry/OperatorIntersects.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorIntersects.java
rename to src/main/java/com/esri/core/geometry/OperatorIntersects.java
index d7984fa8..ace6c277 100644
--- a/src/com/esri/core/geometry/OperatorIntersects.java
+++ b/src/main/java/com/esri/core/geometry/OperatorIntersects.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorIntersectsLocal.java b/src/main/java/com/esri/core/geometry/OperatorIntersectsLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorIntersectsLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorIntersectsLocal.java
index 5a492095..1abefd6a 100644
--- a/src/com/esri/core/geometry/OperatorIntersectsLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorIntersectsLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorOffset.java b/src/main/java/com/esri/core/geometry/OperatorOffset.java
similarity index 96%
rename from src/com/esri/core/geometry/OperatorOffset.java
rename to src/main/java/com/esri/core/geometry/OperatorOffset.java
index 910ccd8a..bdcf5005 100644
--- a/src/com/esri/core/geometry/OperatorOffset.java
+++ b/src/main/java/com/esri/core/geometry/OperatorOffset.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ public enum JoinType {
*
* The offset operation creates a geometry that is a constant distance from
* an input polyline or polygon. It is similar to buffering, but produces a
- * one sided result. If offsetDistance > 0, then the offset geometry is
+ * one sided result. If offsetDistance greater than 0, then the offset geometry is
* constructed to the right of the oriented input geometry, otherwise it is
* constructed to the left. For a simple polygon, the orientation of outer
* rings is clockwise and for inner rings it is counter clockwise. So the
@@ -82,7 +82,7 @@ public abstract GeometryCursor execute(GeometryCursor inputGeometries,
*
* The offset operation creates a geometry that is a constant distance from
* an input polyline or polygon. It is similar to buffering, but produces a
- * one sided result. If offsetDistance > 0, then the offset geometry is
+ * one sided result. If offsetDistance greater than 0, then the offset geometry is
* constructed to the right of the oriented input geometry, otherwise it is
* constructed to the left. For a simple polygon, the orientation of outer
* rings is clockwise and for inner rings it is counter clockwise. So the
diff --git a/src/com/esri/core/geometry/OperatorOffsetCursor.java b/src/main/java/com/esri/core/geometry/OperatorOffsetCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorOffsetCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorOffsetCursor.java
index 5f27c667..76f1f982 100644
--- a/src/com/esri/core/geometry/OperatorOffsetCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorOffsetCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorOffsetLocal.java b/src/main/java/com/esri/core/geometry/OperatorOffsetLocal.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorOffsetLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorOffsetLocal.java
index 7006b42d..06c7f3c6 100644
--- a/src/com/esri/core/geometry/OperatorOffsetLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorOffsetLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorOverlaps.java b/src/main/java/com/esri/core/geometry/OperatorOverlaps.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorOverlaps.java
rename to src/main/java/com/esri/core/geometry/OperatorOverlaps.java
index d1a362b4..c7b3b207 100644
--- a/src/com/esri/core/geometry/OperatorOverlaps.java
+++ b/src/main/java/com/esri/core/geometry/OperatorOverlaps.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorOverlapsLocal.java b/src/main/java/com/esri/core/geometry/OperatorOverlapsLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorOverlapsLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorOverlapsLocal.java
index f767cafd..f9114687 100644
--- a/src/com/esri/core/geometry/OperatorOverlapsLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorOverlapsLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorProject.java b/src/main/java/com/esri/core/geometry/OperatorProject.java
similarity index 50%
rename from src/com/esri/core/geometry/OperatorProject.java
rename to src/main/java/com/esri/core/geometry/OperatorProject.java
index cfd1bec1..db74ae12 100644
--- a/src/com/esri/core/geometry/OperatorProject.java
+++ b/src/main/java/com/esri/core/geometry/OperatorProject.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -71,11 +71,39 @@ public abstract int transform(ProjectionTransformation transform,
* @return projected coordinates in the interleaved form.
*/
public abstract double[] transform(ProjectionTransformation transform,
- double[] coordsSrc, int pointCount);
+ double[] coordsSrc, int pointCount);
+
+ /**
+ * Folds a geometry into the 360 degree range of the associated spatial reference. If the spatial reference be a 'pannable' PCS or GCS. For other spatial types, the function throws an invalid
+ * argument exception. A pannable PCS it a Rectangular PCS where the x coordinate range is equivalent to a 360 degree range on the defining geographic Coordinate System(GCS). If the spatial
+ * reference is a GCS then it is always pannable(default 360 range for spatial reference in GCS coordinates is -180 to 180)
+ *
+ * If the geometry is an Envelope fold_into_360_range returns a polygon, unless the Envelope is empty, in which case the empty envelope is returned. The result geometry will be completely inside of
+ * the coordinate system extent. The folding happens where geometry intersects the min or max meridian of the spatial reference and when geometry is completely outside of the min-max meridian range.
+ * Folding does not preserve geodetic area or length. Folding does not preserve perimeter of a polygon.
+ *
+ * @param geom The geometry to be folded.
+ * @param pannableSR The pannable Spatial Reference.
+ * @return Folded geometry.
+ */
+ public abstract Geometry foldInto360Range(Geometry geom, SpatialReference pannableSR);
+
+ /**
+ * Same as fold_into_360_range. The difference is that this function preserves geodetic area of polygons and geodetic length of polylines. It does not preserve regular area and length or perimeter
+ * of polygons. Also, this function might change tangent of the lines at the points of folding.
+ *
+ * If the geometry is an Envelope fold_into_360_range returns a polygon, unless the Envelope is empty, in which case the empty envelope is returned. The result geometry will be completely inside of
+ * the coordinate system extent. The folding happens where geometry intersects the min or max meridian of the spatial reference and when geometry is completely outside of the min-max meridian range.
+ *
+ * @param geom The geometry to be folded.
+ * @param pannableSR The pannable Spatial Reference.
+ * @param curveType The type of geodetic curve to use to produce vertices at the points of folding. \return Folded geometry.
+ */
+ public abstract Geometry foldInto360RangeGeodetic(Geometry geom, SpatialReference pannableSR, int curveType);
public static OperatorProject local() {
return (OperatorProject) OperatorFactoryLocal.getInstance()
- .getOperator(Type.Project);
+ .getOperator(Type.Project);
}
}
diff --git a/src/com/esri/core/geometry/OperatorProjectLocal.java b/src/main/java/com/esri/core/geometry/OperatorProjectLocal.java
similarity index 79%
rename from src/com/esri/core/geometry/OperatorProjectLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorProjectLocal.java
index c44c7e1d..ae753433 100644
--- a/src/com/esri/core/geometry/OperatorProjectLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorProjectLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -49,4 +49,15 @@ public double[] transform(ProjectionTransformation transform,
throw new GeometryException("not implemented");
}
+ @Override
+ public Geometry foldInto360RangeGeodetic(/* const */Geometry _geom, /* const */
+ SpatialReference pannableSR, /* GeodeticCurveType */int curveType) {
+ throw new GeometryException("not implemented");
+ }
+
+ @Override
+ public Geometry foldInto360Range(/* const */Geometry geom, /* const */
+ SpatialReference pannableSR) {
+ throw new GeometryException("not implemented");
+ }
}
diff --git a/src/com/esri/core/geometry/OperatorProximity2D.java b/src/main/java/com/esri/core/geometry/OperatorProximity2D.java
similarity index 61%
rename from src/com/esri/core/geometry/OperatorProximity2D.java
rename to src/main/java/com/esri/core/geometry/OperatorProximity2D.java
index d8b5b33b..7449fc95 100644
--- a/src/com/esri/core/geometry/OperatorProximity2D.java
+++ b/src/main/java/com/esri/core/geometry/OperatorProximity2D.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -36,7 +36,27 @@ public Type getType() {
}
/**
- * Returns the nearest coordinate on the Geometry to the given input point.
+ *Returns the nearest coordinate on the Geometry to the given input point.
+ *@param geom The input Geometry.
+ *@param inputPoint The query point.
+ *@param bTestPolygonInterior When true and geom is a polygon, the function will test if the input_point is inside of the polygon. Points that are
+ *inside of the polygon have zero distance to the polygon. When false, the function will not check if the point is inside of the polygon,
+ *but only determine proximity to the boundary.
+ *@param bCalculateLeftRightSide The function will calculate left/right side of polylines or polygons when the parameter is True.
+ *\return Returns the result of proximity calculation. See Proximity_2D_result.
+ */
+ public abstract Proximity2DResult getNearestCoordinate(Geometry geom,
+ Point inputPoint, boolean bTestPolygonInterior,
+ boolean bCalculateLeftRightSide);
+
+ /**
+ *Returns the nearest coordinate on the Geometry to the given input point.
+ *@param geom The input Geometry.
+ *@param inputPoint The query point.
+ *@param bTestPolygonInterior When true and geom is a polygon, the function will test if the input_point is inside of the polygon. Points that are
+ *inside of the polygon have zero distance to the polygon. When false, the function will not check if the point is inside of the polygon,
+ *but only determine proximity to the boundary.
+ *\return Returns the result of proximity calculation. See Proximity_2D_result.
*/
public abstract Proximity2DResult getNearestCoordinate(Geometry geom,
Point inputPoint, boolean bTestPolygonInterior);
@@ -74,4 +94,8 @@ public static OperatorProximity2D local() {
.getOperator(Type.Proximity2D);
}
+ interface ProxResultInfo {
+ static final int rightSide = 0x1;
+ }
+
}
diff --git a/src/com/esri/core/geometry/OperatorProximity2DLocal.java b/src/main/java/com/esri/core/geometry/OperatorProximity2DLocal.java
similarity index 54%
rename from src/com/esri/core/geometry/OperatorProximity2DLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorProximity2DLocal.java
index 89171166..d62f514d 100644
--- a/src/com/esri/core/geometry/OperatorProximity2DLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorProximity2DLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -30,9 +30,199 @@
class OperatorProximity2DLocal extends OperatorProximity2D {
+ class Side_helper {
+ int m_i1;
+ int m_i2;
+ boolean m_bRight1;
+ boolean m_bRight2;
+
+ void reset() {
+ m_i1 = -1;
+ m_i2 = -1;
+ m_bRight1 = false;
+ m_bRight2 = false;
+ }
+
+ int find_non_degenerate(SegmentIterator segIter, int vertexIndex,
+ int pathIndex) {
+ segIter.resetToVertex(vertexIndex, pathIndex);
+
+ while (segIter.hasNextSegment()) {
+ Segment segment = segIter.nextSegment();
+ double length = segment.calculateLength2D();
+
+ if (length != 0.0)
+ return segIter.getStartPointIndex();
+ }
+
+ segIter.resetToVertex(vertexIndex, pathIndex);
+
+ while (segIter.hasPreviousSegment()) {
+ Segment segment = segIter.previousSegment();
+ double length = segment.calculateLength2D();
+
+ if (length != 0)
+ return segIter.getStartPointIndex();
+ }
+
+ return -1;
+ }
+
+ int find_prev_non_degenerate(SegmentIterator segIter, int index) {
+ segIter.resetToVertex(index, -1);
+
+ while (segIter.hasPreviousSegment()) {
+ Segment segment = segIter.previousSegment();
+ double length = segment.calculateLength2D();
+
+ if (length != 0)
+ return segIter.getStartPointIndex();
+ }
+
+ return -1;
+ }
+
+ int find_next_non_degenerate(SegmentIterator segIter, int index) {
+ segIter.resetToVertex(index, -1);
+ segIter.nextSegment();
+
+ while (segIter.hasNextSegment()) {
+ Segment segment = segIter.nextSegment();
+ double length = segment.calculateLength2D();
+
+ if (length != 0)
+ return segIter.getStartPointIndex();
+ }
+
+ return -1;
+ }
+
+ void find_analysis_pair_from_index(Point2D inputPoint,
+ SegmentIterator segIter, int vertexIndex, int pathIndex) {
+ m_i1 = find_non_degenerate(segIter, vertexIndex, pathIndex);
+
+ if (m_i1 != -1) {
+ segIter.resetToVertex(m_i1, -1);
+ Segment segment1 = segIter.nextSegment();
+ double t1 = segment1.getClosestCoordinate(inputPoint, false);
+ Point2D p1 = segment1.getCoord2D(t1);
+ double d1 = Point2D.sqrDistance(p1, inputPoint);
+ Point2D pq = new Point2D();
+ pq.setCoords(p1);
+ pq.sub(segment1.getStartXY());
+ Point2D pr = new Point2D();
+ pr.setCoords(inputPoint);
+ pr.sub(segment1.getStartXY());
+ m_bRight1 = (pq.crossProduct(pr) < 0);
+
+ m_i2 = find_next_non_degenerate(segIter, m_i1);
+ if (m_i2 != -1) {
+ segIter.resetToVertex(m_i2, -1);
+ Segment segment2 = segIter.nextSegment();
+ double t2 = segment2
+ .getClosestCoordinate(inputPoint, false);
+ Point2D p2 = segment2.getCoord2D(t2);
+ double d2 = Point2D.sqrDistance(p2, inputPoint);
+
+ if (d2 > d1) {
+ m_i2 = -1;
+ } else {
+ pq.setCoords(p2);
+ pq.sub(segment2.getStartXY());
+ pr.setCoords(inputPoint);
+ pr.sub(segment2.getStartXY());
+ m_bRight2 = (pq.crossProduct(pr) < 0);
+ }
+ }
+
+ if (m_i2 == -1) {
+ m_i2 = find_prev_non_degenerate(segIter, m_i1);
+ if (m_i2 != -1) {
+ segIter.resetToVertex(m_i2, -1);
+ Segment segment2 = segIter.nextSegment();
+ double t2 = segment2.getClosestCoordinate(inputPoint,
+ false);
+ Point2D p2 = segment2.getCoord2D(t2);
+ double d2 = Point2D.sqrDistance(p2, inputPoint);
+
+ if (d2 > d1)
+ m_i2 = -1;
+ else {
+ pq.setCoords(p2);
+ pq.sub(segment2.getStartXY());
+ pr.setCoords(inputPoint);
+ pr.sub(segment2.getStartXY());
+ m_bRight2 = (pq.crossProduct(pr) < 0);
+
+ int itemp = m_i1;
+ m_i1 = m_i2;
+ m_i2 = itemp;
+
+ boolean btemp = m_bRight1;
+ m_bRight1 = m_bRight2;
+ m_bRight2 = btemp;
+ }
+ }
+ }
+ }
+ }
+
+ // Try to find two segements that are not degenerate
+ boolean calc_side(Point2D inputPoint, boolean bRight,
+ MultiPath multipath, int vertexIndex, int pathIndex) {
+ SegmentIterator segIter = multipath.querySegmentIterator();
+
+ find_analysis_pair_from_index(inputPoint, segIter, vertexIndex,
+ pathIndex);
+
+ if (m_i1 != -1 && m_i2 == -1) {// could not find a pair of segments
+ return m_bRight1;
+ }
+
+ if (m_i1 != -1 && m_i2 != -1) {
+ if (m_bRight1 == m_bRight2)
+ return m_bRight1;// no conflicting result for the side
+ else {
+ // the conflicting result, that we are trying to resolve,
+ // happens in the obtuse (outer) side of the turn only.
+ segIter.resetToVertex(m_i1, -1);
+ Segment segment1 = segIter.nextSegment();
+ Point2D tang1 = segment1._getTangent(1.0);
+
+ segIter.resetToVertex(m_i2, -1);
+ Segment segment2 = segIter.nextSegment();
+ Point2D tang2 = segment2._getTangent(0.0);
+
+ double cross = tang1.crossProduct(tang2);
+
+ if (cross >= 0) // the obtuse angle is on the right side
+ {
+ return true;
+ } else // the obtuse angle is on the right side
+ {
+ return false;
+ }
+ }
+ } else {
+ assert (m_i1 == -1 && m_i2 == -1);
+ return bRight;// could not resolve the side. So just return the
+ // old value.
+ }
+ }
+ }
+
@Override
public Proximity2DResult getNearestCoordinate(Geometry geom,
Point inputPoint, boolean bTestPolygonInterior) {
+
+ return getNearestCoordinate(geom, inputPoint, bTestPolygonInterior,
+ false);
+ }
+
+ @Override
+ public Proximity2DResult getNearestCoordinate(Geometry geom,
+ Point inputPoint, boolean bTestPolygonInterior,
+ boolean bCalculateLeftRightSide) {
if (geom.isEmpty())
return new Proximity2DResult();
@@ -55,8 +245,8 @@ public Proximity2DResult getNearestCoordinate(Geometry geom,
(MultiVertexGeometry) proxmityTestGeom, inputPoint2D);
case Geometry.GeometryType.Polyline:
case Geometry.GeometryType.Polygon:
- return polyPathGetNearestCoordinate((MultiPath) proxmityTestGeom,
- inputPoint2D, bTestPolygonInterior);
+ return multiPathGetNearestCoordinate((MultiPath) proxmityTestGeom,
+ inputPoint2D, bTestPolygonInterior, bCalculateLeftRightSide);
default: {
throw new GeometryException("not implemented");
}
@@ -129,64 +319,92 @@ public Proximity2DResult[] getNearestVertices(Geometry geom,
}
}
- Proximity2DResult polyPathGetNearestCoordinate(MultiPath geom,
- Point2D inputPoint, boolean bTestPolygonInterior) {
- Proximity2DResult result = new Proximity2DResult();
+ Proximity2DResult multiPathGetNearestCoordinate(MultiPath geom,
+ Point2D inputPoint, boolean bTestPolygonInterior,
+ boolean bCalculateLeftRightSide) {
+ if (geom.getType() == Geometry.Type.Polygon && bTestPolygonInterior) {
+ Envelope2D env = new Envelope2D();
+ geom.queryEnvelope2D(env);
+ double tolerance = InternalUtils.calculateToleranceFromGeometry(
+ null, env, false);
+
+ PolygonUtils.PiPResult pipResult;
- if (geom.getType() == (Geometry.Type.Polygon) && bTestPolygonInterior) {
- OperatorFactoryLocal factory = OperatorFactoryLocal.getInstance();
- OperatorDisjoint operatorDisjoint = (OperatorDisjoint) factory
- .getOperator(Type.Disjoint);
+ if (bCalculateLeftRightSide)
+ pipResult = PolygonUtils.isPointInPolygon2D((Polygon) geom,
+ inputPoint, 0.0);
+ else
+ pipResult = PolygonUtils.isPointInPolygon2D((Polygon) geom,
+ inputPoint, tolerance);
- Point point = new Point(geom.getDescription());
- point.setXY(inputPoint.x, inputPoint.y);
+ if (pipResult != PolygonUtils.PiPResult.PiPOutside) {
+ Proximity2DResult result = new Proximity2DResult(inputPoint, 0,
+ 0.0);
+
+ if (bCalculateLeftRightSide)
+ result.setRightSide(true);
- boolean disjoint = operatorDisjoint
- .execute(geom, point, null, null);
- if (!disjoint) {
- result._setParams(inputPoint.x, inputPoint.y, 0, 0.0);
return result;
}
}
- MultiPathImpl mpImpl = (MultiPathImpl) geom._getImpl();
- SegmentIteratorImpl segIter = mpImpl.querySegmentIterator();
+ SegmentIterator segIter = geom.querySegmentIterator();
- Point2D closest = null;// new Point2D();
- int closestIndex = 0;
+ Point2D closest = new Point2D();
+ int closestVertexIndex = -1;
+ int closestPathIndex = -1;
double closestDistanceSq = NumberUtils.doubleMax();
+ boolean bRight = false;
+ int num_candidates = 0;
while (segIter.nextPath()) {
while (segIter.hasNextSegment()) {
Segment segment = segIter.nextSegment();
double t = segment.getClosestCoordinate(inputPoint, false);
+
Point2D point = segment.getCoord2D(t);
double distanceSq = Point2D.sqrDistance(point, inputPoint);
if (distanceSq < closestDistanceSq) {
+ num_candidates = 1;
closest = point;
- closestIndex = segIter.getStartPointIndex();
+ closestVertexIndex = segIter.getStartPointIndex();
+ closestPathIndex = segIter.getPathIndex();
closestDistanceSq = distanceSq;
+ } else if (distanceSq == closestDistanceSq) {
+ num_candidates++;
}
}
}
- result._setParams(closest.x, closest.y, closestIndex,
- Math.sqrt(closestDistanceSq));
+ Proximity2DResult result = new Proximity2DResult(closest,
+ closestVertexIndex, Math.sqrt(closestDistanceSq));
- return result;
- }
+ if (bCalculateLeftRightSide) {
+ segIter.resetToVertex(closestVertexIndex, closestPathIndex);
+ Segment segment = segIter.nextSegment();
+ bRight = (Point2D.orientationRobust(inputPoint,
+ segment.getStartXY(), segment.getEndXY()) < 0);
- Proximity2DResult pointGetNearestVertex(Point geom, Point2D inputPoint) {
- Proximity2DResult result = new Proximity2DResult();
+ if (num_candidates > 1) {
+ Side_helper sideHelper = new Side_helper();
+ sideHelper.reset();
+ bRight = sideHelper.calc_side(inputPoint, bRight, geom,
+ closestVertexIndex, closestPathIndex);
+ }
- Point2D pt = geom.getXY();
- double distance = Point2D.distance(pt, inputPoint);
- result._setParams(pt.x, pt.y, 0, distance);
+ result.setRightSide(bRight);
+ }
return result;
}
+ Proximity2DResult pointGetNearestVertex(Point geom, Point2D input_point) {
+ Point2D pt = geom.getXY();
+ double distance = Point2D.distance(pt, input_point);
+ return new Proximity2DResult(pt, 0, distance);
+ }
+
Proximity2DResult multiVertexGetNearestVertex(MultiVertexGeometry geom,
Point2D inputPoint) {
MultiVertexGeometryImpl mpImpl = (MultiVertexGeometryImpl) geom
diff --git a/src/com/esri/core/geometry/OperatorRelate.java b/src/main/java/com/esri/core/geometry/OperatorRelate.java
similarity index 77%
rename from src/com/esri/core/geometry/OperatorRelate.java
rename to src/main/java/com/esri/core/geometry/OperatorRelate.java
index 258a71bf..d5542990 100644
--- a/src/com/esri/core/geometry/OperatorRelate.java
+++ b/src/main/java/com/esri/core/geometry/OperatorRelate.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
package com.esri.core.geometry;
+import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
import com.esri.core.geometry.Operator.Type;
/**
@@ -51,5 +52,19 @@ public static OperatorRelate local() {
return (OperatorRelate) OperatorFactoryLocal.getInstance().getOperator(
Type.Relate);
}
+
+ @Override
+ public boolean canAccelerateGeometry(Geometry geometry) {
+ return RelationalOperations.Accelerate_helper
+ .can_accelerate_geometry(geometry);
+ }
+
+ @Override
+ public boolean accelerateGeometry(Geometry geometry,
+ SpatialReference spatialReference,
+ GeometryAccelerationDegree accelDegree) {
+ return RelationalOperations.Accelerate_helper.accelerate_geometry(
+ geometry, spatialReference, accelDegree);
+ }
}
diff --git a/src/com/esri/core/geometry/OperatorRelateLocal.java b/src/main/java/com/esri/core/geometry/OperatorRelateLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorRelateLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorRelateLocal.java
index c83fbee1..88af8ad0 100644
--- a/src/com/esri/core/geometry/OperatorRelateLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorRelateLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensify.java b/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensify.java
new file mode 100644
index 00000000..b25d66e0
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensify.java
@@ -0,0 +1,71 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+/**
+ * Densifies geometries preserving the shape of the segments in a given spatial reference by length and/or deviation. The elliptic arc lengths of the resulting line segments are no longer than the
+ * given max length, and the line segments will be closer than the given max deviation to both the original segment curve and the joining elliptic arcs.
+ */
+abstract class OperatorShapePreservingDensify extends Operator {
+
+ @Override
+ public Type getType() {
+ return Type.ShapePreservingDensify;
+ }
+
+ /**
+ * Performs the Shape Preserving Densify operation on the geometry set. Attributes are interpolated along the scalar t-values of the input segments obtained from the length ratios along the
+ * densified segments.
+ *
+ * @param geoms The geometries to be densified.
+ * @param sr The spatial reference of the geometries.
+ * @param maxLengthMeters The maximum segment length allowed. Must be a positive value to be used. Pass zero or NaN to disable densification by length.
+ * @param maxDeviationMeters The maximum deviation. Must be a positive value to be used. Pass zero or NaN to disable densification by deviation.
+ * @param reserved Must be 0 or NaN. Reserved for future use. Throws and exception if not NaN or 0.
+ * @return Returns the densified geometries (It does nothing to geometries with dim less than 1, but simply passes them along).
+ *
+ * The operation always starts from the lowest point on the segment, thus guaranteeing that topologically equal segments are always densified exactly the same.
+ */
+ public abstract GeometryCursor execute(GeometryCursor geoms, SpatialReference sr, double maxLengthMeters, double maxDeviationMeters, double reserved, ProgressTracker progressTracker);
+
+ /**
+ * Performs the Shape Preserving Densify operation on the geometry. Attributes are interpolated along the scalar t-values of the input segments obtained from the length ratios along the densified
+ * segments.
+ *
+ * @param geom The geometry to be densified.
+ * @param sr The spatial reference of the geometry.
+ * @param maxLengthMeters The maximum segment length allowed. Must be a positive value to be used. Pass zero or NaN to disable densification by length.
+ * @param maxDeviationMeters The maximum deviation. Must be a positive value to be used. Pass zero or NaN to disable densification by deviation.
+ * @param reserved Must be 0 or NaN. Reserved for future use. Throws and exception if not NaN or 0.
+ * @return Returns the densified geometries (It does nothing to geometries with dim less than 1, but simply passes them along).
+ *
+ * The operation always starts from the lowest point on the segment, thus guaranteeing that topologically equal segments are always densified exactly the same.
+ */
+ public abstract Geometry execute(Geometry geom, SpatialReference sr, double maxLengthMeters, double maxDeviationMeters, double reserved, ProgressTracker progressTracker);
+
+ public static OperatorShapePreservingDensify local() {
+ return (OperatorShapePreservingDensify) OperatorFactoryLocal.getInstance()
+ .getOperator(Type.ShapePreservingDensify);
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensifyLocal.java b/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensifyLocal.java
new file mode 100644
index 00000000..68fd0a5c
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensifyLocal.java
@@ -0,0 +1,44 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+//This is a stub
+class OperatorShapePreservingDensifyLocal extends
+ OperatorShapePreservingDensify {
+
+ @Override
+ public GeometryCursor execute(GeometryCursor geoms, SpatialReference sr,
+ double maxLengthMeters, double maxDeviationMeters, double reserved,
+ ProgressTracker progressTracker) {
+ throw new GeometryException("not implemented");
+ }
+
+ @Override
+ public Geometry execute(Geometry geom, SpatialReference sr,
+ double maxLengthMeters, double maxDeviationMeters, double reserved,
+ ProgressTracker progressTracker) {
+ throw new GeometryException("not implemented");
+ }
+}
diff --git a/src/com/esri/core/geometry/OperatorSimpleRelation.java b/src/main/java/com/esri/core/geometry/OperatorSimpleRelation.java
similarity index 73%
rename from src/com/esri/core/geometry/OperatorSimpleRelation.java
rename to src/main/java/com/esri/core/geometry/OperatorSimpleRelation.java
index 2cb90a96..1a08cf6d 100644
--- a/src/com/esri/core/geometry/OperatorSimpleRelation.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimpleRelation.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -41,22 +41,15 @@ public abstract boolean execute(Geometry inputGeom1, Geometry inputGeom2,
@Override
public boolean canAccelerateGeometry(Geometry geometry) {
- return RasterizedGeometry2D.canUseAccelerator(geometry);
+ return RelationalOperations.Accelerate_helper
+ .can_accelerate_geometry(geometry);
}
-
+
@Override
public boolean accelerateGeometry(Geometry geometry,
SpatialReference spatialReference,
GeometryAccelerationDegree accelDegree) {
- if (!canAccelerateGeometry(geometry))
- return false;
-
- double tol = spatialReference != null ? spatialReference
- .getTolerance(VertexDescription.Semantics.POSITION) : 0;
- boolean accelerated = ((MultiVertexGeometryImpl) geometry._getImpl())
- ._buildQuadTreeAccelerator(accelDegree);
- accelerated |= ((MultiVertexGeometryImpl) geometry._getImpl())
- ._buildRasterizedGeometryAccelerator(tol, accelDegree);
- return accelerated;
+ return RelationalOperations.Accelerate_helper.accelerate_geometry(
+ geometry, spatialReference, accelDegree);
}
}
diff --git a/src/main/java/com/esri/core/geometry/OperatorSimplify.java b/src/main/java/com/esri/core/geometry/OperatorSimplify.java
new file mode 100644
index 00000000..3e9beca9
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplify.java
@@ -0,0 +1,107 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.Operator.Type;
+
+/**
+ * Simplifies the geometry or determines if the geometry is simple. The goal of the OperatorSimplify is to produce a geometry that is
+ * valid for the Geodatabase to store without additional processing.
+ *
+ * The Geoprocessing tool CheckGeometries should accept geometries
+ * produced by this operator's execute method. For Polylines the effect of execute is the same as
+ * IPolyline6.NonPlanarSimplify, while for the Polygons and Multipoints it is same as ITopologicalOperator.Simplify.
+ * For the Point class this operator does nothing, and the point is always simple.
+ *
+ * The isSimpleAsFeature should return true after the execute method.
+ *
+ * See also OperatorSimplifyOGC.
+ *
+ */
+public abstract class OperatorSimplify extends Operator {
+ @Override
+ public Operator.Type getType() {
+ return Operator.Type.Simplify;
+ }
+
+ /**
+ *Tests if the Geometry is simple.
+ *@param geom The Geometry to be tested.
+ *@param spatialRef Spatial reference from which the tolerance is obtained. Can be null, then a
+ *very small tolerance value is derived from the geometry bounds.
+ *@param bForceTest When True, the Geometry will be tested regardless of the internal IsKnownSimple flag.
+ *@param result if not null, will contain the results of the check.
+ *@param progressTracker Allows cancellation of a long operation. Can be null.
+ **/
+ public abstract boolean isSimpleAsFeature(Geometry geom,
+ SpatialReference spatialRef, boolean bForceTest,
+ NonSimpleResult result, ProgressTracker progressTracker);
+
+ /**
+ *Tests if the Geometry is simple (second call will use a cached IsKnownSimple flag and immediately return).
+ *@param geom The Geometry to be tested.
+ *@param spatialRef Spatial reference from which the tolerance is obtained. Can be null, then a
+ *very small tolerance value is derived from the geometry bounds.
+ *@param progressTracker Allows cancellation of a long operation. Can be null.
+ *
+ */
+ public boolean isSimpleAsFeature(Geometry geom,
+ SpatialReference spatialRef, ProgressTracker progressTracker) {
+ return isSimpleAsFeature(geom, spatialRef, false, null, progressTracker);
+ }
+
+ /**
+ *Performs the Simplify operation on the geometry cursor.
+ *@param geoms Geometries to simplify.
+ *@param sr Spatial reference from which the tolerance is obtained. When null, the tolerance
+ *will be derived individually for each geometry from its bounds.
+ *@param bForceSimplify When True, the Geometry will be simplified regardless of the internal IsKnownSimple flag.
+ *@param progressTracker Allows cancellation of a long operation. Can be null.
+ *@return Returns a GeometryCursor of simplified geometries.
+ *
+ *The isSimpleAsFeature returns true after this method.
+ */
+ public abstract GeometryCursor execute(GeometryCursor geoms,
+ SpatialReference sr, boolean bForceSimplify,
+ ProgressTracker progressTracker);
+
+ /**
+ *Performs the Simplify operation on the geometry.
+ *@param geom Geometry to simplify.
+ *@param sr Spatial reference from which the tolerance is obtained. When null, the tolerance
+ *will be derived individually for each geometry from its bounds.
+ *@param bForceSimplify When True, the Geometry will be simplified regardless of the internal IsKnownSimple flag.
+ *@param progressTracker Allows cancellation of a long operation. Can be null.
+ *@return Returns a simple geometry.
+ *
+ *The isSimpleAsFeature returns true after this method.
+ */
+ public abstract Geometry execute(Geometry geom, SpatialReference sr,
+ boolean bForceSimplify, ProgressTracker progressTracker);
+
+ public static OperatorSimplify local() {
+ return (OperatorSimplify) OperatorFactoryLocal.getInstance()
+ .getOperator(Type.Simplify);
+ }
+}
diff --git a/src/com/esri/core/geometry/OperatorSimplifyCursor.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorSimplifyCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorSimplifyCursor.java
index 4be821a8..19c920df 100644
--- a/src/com/esri/core/geometry/OperatorSimplifyCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplifyCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorSimplifyCursorOGC.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyCursorOGC.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorSimplifyCursorOGC.java
rename to src/main/java/com/esri/core/geometry/OperatorSimplifyCursorOGC.java
index 277724d6..15e726af 100644
--- a/src/com/esri/core/geometry/OperatorSimplifyCursorOGC.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplifyCursorOGC.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorSimplifyLocal.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocal.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorSimplifyLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorSimplifyLocal.java
index 6cb16dc1..4edc081e 100644
--- a/src/com/esri/core/geometry/OperatorSimplifyLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorSimplifyLocalHelper.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocalHelper.java
similarity index 96%
rename from src/com/esri/core/geometry/OperatorSimplifyLocalHelper.java
rename to src/main/java/com/esri/core/geometry/OperatorSimplifyLocalHelper.java
index 2f726e53..2513693e 100644
--- a/src/com/esri/core/geometry/OperatorSimplifyLocalHelper.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocalHelper.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -152,8 +152,8 @@ private boolean testToleranceDistance_(int xyindex1, int xyindex2) {
double y1 = m_xy.read(2 * xyindex1 + 1);
double x2 = m_xy.read(2 * xyindex2);
double y2 = m_xy.read(2 * xyindex2 + 1);
- boolean b = !Clusterer.isClusterCandidate(x1, y1, x2, y2,
- m_toleranceIsSimple);
+ boolean b = !Clusterer.isClusterCandidate_(x1, y1, x2, y2,
+ m_toleranceIsSimple * m_toleranceIsSimple);
if (!b) {
if (m_geometry.getDimension() == 0)
return false;
@@ -332,7 +332,7 @@ private boolean checkCrackingPlanesweep_() // cracker,that uses planesweep
EditShape editShape = new EditShape();
editShape.addGeometry(m_geometry);
NonSimpleResult result = new NonSimpleResult();
- boolean bNonSimple = Cracker.needsCracking(editShape,
+ boolean bNonSimple = Cracker.needsCracking(false, editShape,
m_toleranceIsSimple, result, m_progressTracker);
if (bNonSimple) {
result.m_vertexIndex1 = editShape
@@ -476,10 +476,12 @@ boolean checkSelfIntersectionsPolylinePlanar_() {
|| (xyindex == path_last);
if (m_bOGCRestrictions)
vi_prev.boundary = !is_closed_path && vi_prev.end_point;
- else
+ else {
// for regular planar simplify, only the end points are allowed
// to coincide
vi_prev.boundary = vi_prev.end_point;
+ }
+
vi_prev.ipath = ipath;
vi_prev.x = pt.x;
vi_prev.y = pt.y;
@@ -506,11 +508,11 @@ boolean checkSelfIntersectionsPolylinePlanar_() {
boolean end_point = (xyindex == path_start)
|| (xyindex == path_last);
if (m_bOGCRestrictions)
- boundary = !is_closed_path && vi_prev.end_point;
+ boundary = !is_closed_path && end_point;
else
// for regular planar simplify, only the end points are allowed
// to coincide
- boundary = vi_prev.end_point;
+ boundary = end_point;
vi.x = pt.x;
vi.y = pt.y;
@@ -522,22 +524,12 @@ boolean checkSelfIntersectionsPolylinePlanar_() {
if (vi.x == vi_prev.x && vi.y == vi_prev.y) {
if (m_bOGCRestrictions) {
if (!vi.boundary || !vi_prev.boundary) {
+ // check that this is not the endpoints of a closed path
if ((vi.ipath != vi_prev.ipath)
- || (!vi.end_point && !vi_prev.end_point))// check
- // that
- // this
- // is
- // not
- // the
- // endpoints
- // of
- // a
- // closed
- // path
- {
+ || (!vi.end_point && !vi_prev.end_point)) {
// one of coincident vertices is not on the boundary
- // this is either Non_simple_result::cross_over or
- // Non_simple_result::ogc_self_tangency.
+ // this is either NonSimpleResult.CrossOver or
+ // NonSimpleResult.OGCPolylineSelfTangency.
// too expensive to distinguish between the two.
m_nonSimpleResult = new NonSimpleResult(
NonSimpleResult.Reason.OGCPolylineSelfTangency,
@@ -546,12 +538,9 @@ boolean checkSelfIntersectionsPolylinePlanar_() {
}
}
} else {
- if (!vi.end_point || !vi_prev.end_point) {// one of
- // coincident
- // vertices is
- // not an
- // endpoint
- m_nonSimpleResult = new NonSimpleResult(
+ if (!vi.end_point || !vi_prev.end_point) {
+ //one of coincident vertices is not an endpoint
+ m_nonSimpleResult = new NonSimpleResult(
NonSimpleResult.Reason.CrossOver, vi.ivertex,
vi_prev.ivertex);
return false;// common point not on the boundary
@@ -1258,7 +1247,7 @@ private Edge createEdge_(/* const */Segment seg, int xyindex, int pathIndex,
if (gt == Geometry.Type.Line) {
edge = createEdgeLine_(seg);
} else {
- throw new GeometryException("internal error"); // implement
+ throw GeometryException.GeometryInternalError(); // implement
// recycling for
// curves
}
@@ -1643,49 +1632,42 @@ MultiVertexGeometry simplifyPlanar_() {
// ((MultiPathImpl)m_geometry._getImpl()).saveToTextFileDbg("c:/temp/_simplifyDbg0.txt");
// }
+ if (m_geometry.getType() == Geometry.Type.Polygon) {
+ if (((Polygon) m_geometry).getFillRule() == Polygon.FillRule.enumFillRuleWinding) {
+ // when the fill rule is winding, we need to call a special
+ // method.
+ return TopologicalOperations.planarSimplify(
+ (MultiVertexGeometry) m_geometry, m_toleranceSimplify,
+ true, false, m_progressTracker);
+ }
+ }
+
m_editShape = new EditShape();
m_editShape.addGeometry(m_geometry);
- assert (m_knownSimpleResult != GeometryXSimple.Strong);
- if (m_knownSimpleResult != GeometryXSimple.Weak) {
- CrackAndCluster.execute(m_editShape, m_toleranceSimplify,
- m_progressTracker);
- }
-
- // if (false)// FIXME:do not forget to change this to if(false)!!!
- // {
- // OperatorSimplify simplify = (OperatorSimplify)
- // (OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Simplify));
- // NonSimpleResult nsres = new NonSimpleResult();
- // Geometry geometry =
- // m_editShape.getGeometry(m_editShape.getFirstGeometry());// extract
- // the result of simplify
- // boolean res = simplify.isSimpleAsFeature(geometry, m_sr, true, nsres,
- // null);
- // if (false)
- // {
- // ((MultiPathImpl)geometry._getImpl()).saveToTextFileDbg("c:/temp/_simplifyDbg.txt");
- // }
- // if (!res)
- // {
- // assert (nsres.m_reason.compareTo(NonSimpleResult.Reason.CrossOver) >=
- // 0);
- // }
- // }
-
- if (m_geometry.getType().equals(Geometry.Type.Polygon)) {
- Simplificator.execute(m_editShape, m_editShape.getFirstGeometry(),
- m_knownSimpleResult);
+ if (m_editShape.getTotalPointCount() != 0) {
+ assert (m_knownSimpleResult != GeometryXSimple.Strong);
+ if (m_knownSimpleResult != GeometryXSimple.Weak) {
+ CrackAndCluster.execute(m_editShape, m_toleranceSimplify,
+ m_progressTracker, true);
+ }
+
+ if (m_geometry.getType().equals(Geometry.Type.Polygon)) {
+ Simplificator.execute(m_editShape, m_editShape.getFirstGeometry(),
+ m_knownSimpleResult, false, m_progressTracker);
+ }
}
-
+
m_geometry = m_editShape.getGeometry(m_editShape.getFirstGeometry()); // extract
// the
// result
// of
// simplify
- if (m_geometry.getType().equals(Geometry.Type.Polygon))
- ((MultiPathImpl) m_geometry._getImpl())._updateOGCFlags();
+ if (m_geometry.getType().equals(Geometry.Type.Polygon)) {
+ ((MultiPathImpl)m_geometry._getImpl())._updateOGCFlags();
+ ((Polygon)m_geometry).setFillRule(Polygon.FillRule.enumFillRuleOddEven);
+ }
// We have simplified the geometry using the given tolerance. Now mark
// the geometry as strong simple,
@@ -1747,10 +1729,10 @@ else if (gt == Geometry.Type.Envelope) {
false));
return bReturnValue ? 1 : 0;
} else if (Geometry.isSegment(gt.value())) {
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// return seg.IsSimple(m_tolerance);
} else if (!Geometry.isMultiVertex(gt.value())) {
- throw new GeometryException("internal error");// What else?
+ throw GeometryException.GeometryInternalError();// What else?
}
double tolerance = InternalUtils.calculateToleranceFromGeometry(
@@ -1845,7 +1827,7 @@ static protected int isSimpleAsFeature(/* const */Geometry geometry, /* const */
} else if (gt == Geometry.Type.Polygon) {
knownSimpleResult = helper.polygonIsSimpleAsFeature_();
} else {
- throw new GeometryException("internal error");// what else?
+ throw GeometryException.GeometryInternalError();// what else?
}
((MultiVertexGeometryImpl) (geometry._getImpl())).setIsSimple(
@@ -1902,7 +1884,7 @@ static int isSimpleOGC(/* const */Geometry geometry, /* const */
|| gt == Geometry.Type.Polygon) {
knownSimpleResult = helper.isSimplePlanarImpl_();
} else {
- throw new GeometryException("internal error");// what else?
+ throw GeometryException.GeometryInternalError();// what else?
}
if (result != null)
@@ -1959,6 +1941,13 @@ static protected Geometry simplifyAsFeature(/* const */Geometry geometry, /* con
// From the first sight it seems the SimplePlanar implies
// SimpleAsFeature.
if (knownSimpleResult == GeometryXSimple.Strong) {
+ if (gt == Geometry.Type.Polygon && ((Polygon)geometry).getFillRule() != Polygon.FillRule.enumFillRuleOddEven)
+ {
+ Geometry res = geometry.copy();
+ ((Polygon)res).setFillRule(Polygon.FillRule.enumFillRuleOddEven);//standardize on odd_even fill rule
+ return res;
+ }
+
return geometry;
}
@@ -1975,7 +1964,7 @@ static protected Geometry simplifyAsFeature(/* const */Geometry geometry, /* con
} else if (gt == Geometry.Type.Polygon) {
result = (Geometry) (helper.polygonSimplifyAsFeature_());
} else {
- throw new GeometryException("internal error"); // what else?
+ throw GeometryException.GeometryInternalError(); // what else?
}
return result;
@@ -2020,12 +2009,11 @@ static Geometry simplifyOGC(/* const */Geometry geometry, /* const */
}
if (!Geometry.isMultiVertex(gt.value())) {
- throw new GeometryException("internal error"); // what else?
+ throw new GeometryException("OGC simplify is not implemented for this geometry type" + gt);
}
- MultiVertexGeometry result = TopologicalOperations.planarSimplify(
- (MultiVertexGeometry) geometry, tolerance, false, false,
- progressTracker);
+ MultiVertexGeometry result = TopologicalOperations.simplifyOGC(
+ (MultiVertexGeometry) geometry, tolerance, false, progressTracker);
return result;
}
@@ -2155,9 +2143,6 @@ private static final class EdgeComparerForSelfIntersection implements
@Override
public int compare(Edge e1, Edge e2) {
- // C++ style with bool operator() would be
- // return parent->edgeAngleCompare_(*e1,*e2) < 0;
-
return parent.edgeAngleCompare_(e1, e2);
}
}
diff --git a/src/com/esri/core/geometry/OperatorSimplifyLocalOGC.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocalOGC.java
similarity index 95%
rename from src/com/esri/core/geometry/OperatorSimplifyLocalOGC.java
rename to src/main/java/com/esri/core/geometry/OperatorSimplifyLocalOGC.java
index 8f6bce0f..6c725abb 100644
--- a/src/com/esri/core/geometry/OperatorSimplifyLocalOGC.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocalOGC.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@
class OperatorSimplifyLocalOGC extends OperatorSimplifyOGC {
- // Reviewed vs. Feb 8 2011
@Override
public GeometryCursor execute(GeometryCursor geoms,
SpatialReference spatialRef, boolean bForceSimplify,
@@ -43,7 +42,6 @@ public boolean isSimpleOGC(Geometry geom, SpatialReference spatialRef,
return res > 0;
}
- // Reviewed vs. Feb 8 2011
@Override
public Geometry execute(Geometry geom, SpatialReference spatialRef,
boolean bForceSimplify, ProgressTracker progressTracker) {
diff --git a/src/main/java/com/esri/core/geometry/OperatorSimplifyOGC.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyOGC.java
new file mode 100644
index 00000000..c04ba0c4
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplifyOGC.java
@@ -0,0 +1,89 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+/**
+ * Simplifies the geometry or determines if the geometry is simple. Follows the OGC specification for the Simple Feature Access
+ * v. 1.2.1 (06-103r4).
+ * Uses tolerance to determine equal vertices or points of intersection.
+ *
+ */
+public abstract class OperatorSimplifyOGC extends Operator {
+ @Override
+ public Operator.Type getType() {
+ return Operator.Type.SimplifyOGC;
+ }
+
+ /**
+ *Tests if the Geometry is simple for OGC specification.
+ *@param geom The Geometry to be tested.
+ *@param spatialRef Spatial reference to obtain the tolerance from. When null, the tolerance
+ *will be derived individually from geometry bounds.
+ *@param bForceTest When True, the Geometry will be tested regardless of the IsKnownSimple flag.
+ *@param progressTracker Allows cancellation of a long operation. Can be null.
+ *
+ *Note: As other methods in the OperatorSimplifyOGC, this method uses tolerance from the spatial reference.
+ *Points that are within the tolerance are considered equal.
+ *
+ *When this method returns true, the OperatorSimplify.isSimpleAsFeature will return true also (this does not necessary happen the other way around).
+ */
+ public abstract boolean isSimpleOGC(Geometry geom,
+ SpatialReference spatialRef, boolean bForceTest,
+ NonSimpleResult result, ProgressTracker progressTracker);
+
+ /**
+ * Processes geometry cursor to ensure its geometries are simple for OGC specification.
+ * @param geoms Geometries to be simplified.
+ * @param sr Spatial reference to obtain the tolerance from. When null, the tolerance
+ * will be derived individually for each geometry from its bounds.
+ * @param bForceSimplify When True, the Geometry will be simplified regardless of the internal IsKnownSimple flag.
+ * @param progressTracker Allows cancellation of a long operation. Can be null.
+ * @return Returns a GeometryCursor of simplified geometries.
+ *
+ * The isSimpleOGC returns true after this call.
+ */
+ public abstract GeometryCursor execute(GeometryCursor geoms,
+ SpatialReference sr, boolean bForceSimplify,
+ ProgressTracker progressTracker);
+
+ /**
+ * Processes geometry to ensure it is simple for OGC specification.
+ * @param geom The geometry to be simplified.
+ * @param sr Spatial reference to obtain the tolerance from. When null, the tolerance
+ * will be derived individually from geometry bounds.
+ * @param bForceSimplify When True, the Geometry will be simplified regardless of the internal IsKnownSimple flag.
+ * @param progressTracker Allows cancellation of a long operation. Can be null.
+ * @return Returns a simple Geometry that should be visually equivalent to the input geometry.
+ *
+ * The isSimpleOGC returns true after this call.
+ */
+ public abstract Geometry execute(Geometry geom, SpatialReference sr,
+ boolean bForceSimplify, ProgressTracker progressTracker);
+
+ public static OperatorSimplifyOGC local() {
+ return (OperatorSimplifyOGC) OperatorFactoryLocal.getInstance()
+ .getOperator(Type.SimplifyOGC);
+ }
+
+}
diff --git a/src/com/esri/core/geometry/OperatorSymmetricDifference.java b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifference.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorSymmetricDifference.java
rename to src/main/java/com/esri/core/geometry/OperatorSymmetricDifference.java
index b21f8745..ea84ce0c 100644
--- a/src/com/esri/core/geometry/OperatorSymmetricDifference.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifference.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
* Symmetric difference (XOR) operation between geometries.
*
*/
-public abstract class OperatorSymmetricDifference extends Operator {
+public abstract class OperatorSymmetricDifference extends Operator implements CombineOperator {
@Override
public Type getType() {
return Type.Difference;
diff --git a/src/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java
rename to src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java
index 92450ce3..3d265593 100644
--- a/src/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java
similarity index 99%
rename from src/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java
index e5de43db..e505a8dd 100644
--- a/src/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorTouches.java b/src/main/java/com/esri/core/geometry/OperatorTouches.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorTouches.java
rename to src/main/java/com/esri/core/geometry/OperatorTouches.java
index a98de285..6ae67f38 100644
--- a/src/com/esri/core/geometry/OperatorTouches.java
+++ b/src/main/java/com/esri/core/geometry/OperatorTouches.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorTouchesLocal.java b/src/main/java/com/esri/core/geometry/OperatorTouchesLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorTouchesLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorTouchesLocal.java
index f18f3541..48d32d89 100644
--- a/src/com/esri/core/geometry/OperatorTouchesLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorTouchesLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorUnion.java b/src/main/java/com/esri/core/geometry/OperatorUnion.java
similarity index 93%
rename from src/com/esri/core/geometry/OperatorUnion.java
rename to src/main/java/com/esri/core/geometry/OperatorUnion.java
index c7cf49b4..8a0a8601 100644
--- a/src/com/esri/core/geometry/OperatorUnion.java
+++ b/src/main/java/com/esri/core/geometry/OperatorUnion.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@
* Union of geometries.
*
*/
-public abstract class OperatorUnion extends Operator {
+public abstract class OperatorUnion extends Operator implements CombineOperator{
@Override
public Type getType() {
return Type.Union;
diff --git a/src/main/java/com/esri/core/geometry/OperatorUnionCursor.java b/src/main/java/com/esri/core/geometry/OperatorUnionCursor.java
new file mode 100644
index 00000000..0ddd88b8
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorUnionCursor.java
@@ -0,0 +1,300 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+final class OperatorUnionCursor extends GeometryCursor {
+
+ private GeometryCursor m_inputGeoms;
+ private ProgressTracker m_progress_tracker;
+ private SpatialReferenceImpl m_spatial_reference;
+ private int m_index = -1;
+ private boolean m_b_done = false;
+ private boolean [] m_had_geometry = new boolean[4];
+ private int [] m_dim_geom_counts = new int [4];
+ private boolean m_b_union_all_dimensions = false;
+ private int m_max_dimension = -1;
+ private int m_added_geoms = 0;
+ private int m_current_dim = -1;
+
+ private final static class Geom_pair
+ {
+ void init() { geom = null; vertex_count = -1; unioned = false; }
+ Geometry geom;
+ int vertex_count;
+ boolean unioned;//true if geometry is a result of union operation
+ }
+
+ final static class Bin_type //bin array and the total vertex count in the bin
+ {
+ int bin_vertex_count = 0;
+ ArrayList geometries = new ArrayList();
+
+ void add_pair(Geom_pair geom)
+ {
+ bin_vertex_count += geom.vertex_count;
+ geometries.add(geom);
+ }
+ void pop_pair()
+ {
+ bin_vertex_count -= geometries.get(geometries.size() - 1).vertex_count;
+ geometries.remove(geometries.size() - 1);
+ }
+ Geom_pair back_pair() { return geometries.get(geometries.size() - 1); }
+ int geom_count() { return geometries.size(); }
+ }
+
+ ArrayList< TreeMap > m_union_bins = new ArrayList< TreeMap >();//for each dimension there is a list of bins sorted by level
+
+ OperatorUnionCursor(GeometryCursor inputGeoms1, SpatialReference sr,
+ ProgressTracker progress_tracker) {
+ m_inputGeoms = inputGeoms1;
+ m_spatial_reference = (SpatialReferenceImpl) (sr);
+ m_progress_tracker = progress_tracker;
+ }
+
+ private Geometry get_result_geometry(int dim) {
+ assert (m_dim_geom_counts[dim] > 0);
+ java.util.TreeMap map = m_union_bins.get(dim);
+ Map.Entry e = map.firstEntry();
+ Bin_type bin = e.getValue();
+
+ Geometry resG;
+ resG = bin.back_pair().geom;
+ boolean unioned = bin.back_pair().unioned;
+ map.remove(e.getKey());
+
+ if (unioned) {
+ resG = OperatorSimplify.local().execute(resG, m_spatial_reference,
+ false, m_progress_tracker);
+ if (dim == 0 && resG.getType() == Geometry.Type.Point) {// must
+ // return
+ // multipoint
+ // for
+ // points
+ MultiPoint mp = new MultiPoint(resG.getDescription());
+ if (!resG.isEmpty())
+ mp.add((Point) resG);
+
+ resG = mp;
+ }
+ }
+
+ return resG;
+ }
+
+ @Override
+ public Geometry next() {
+ if (m_b_done && m_current_dim == m_max_dimension)
+ return null;
+
+ while (!step_()) {
+ }
+
+ if (m_max_dimension == -1)
+ return null;// empty input cursor
+
+ if (m_b_union_all_dimensions) {
+ m_current_dim++;
+ while (true) {
+ if (m_current_dim > m_max_dimension || m_current_dim < 0)
+ throw GeometryException.GeometryInternalError();
+
+ if (m_had_geometry[m_current_dim])
+ break;
+ }
+
+ m_index++;
+ return get_result_geometry(m_current_dim);
+ } else {
+ m_index = 0;
+ assert (m_max_dimension >= 0);
+ m_current_dim = m_max_dimension;
+ return get_result_geometry(m_max_dimension);
+ }
+ }
+
+ @Override
+ public int getGeometryID() {
+ return m_index;
+ }
+
+ private boolean step_(){
+ if (m_b_done)
+ return true;
+
+ Geometry geom = null;
+ if (m_inputGeoms != null)
+ {
+ geom = m_inputGeoms.next();
+ if (geom == null) {
+ m_b_done = true;
+ m_inputGeoms = null;
+ }
+ }
+
+ ProgressTracker.checkAndThrow(m_progress_tracker);
+
+ if (geom != null) {
+ int dim = geom.getDimension();
+ m_had_geometry[dim] = true;
+ if (dim >= m_max_dimension && !m_b_union_all_dimensions)
+ {
+ add_geom(dim, false, geom);
+ if (dim > m_max_dimension && !m_b_union_all_dimensions)
+ {
+ //this geometry has higher dimension than the previously processed one
+ //Therefore we delete all lower dimensions (unless m_b_union_all_dimensions is true).
+ remove_all_bins_with_lower_dimension(dim);
+ }
+ }
+ else
+ {
+ //this geometry is skipped
+ }
+ } else {
+ //geom is null. do nothing
+ }
+
+ if (m_added_geoms > 0) {
+ for (int dim = 0; dim <= m_max_dimension; dim++) {
+ while (m_dim_geom_counts[dim] > 1) {
+ ArrayList batch_to_union = collect_geometries_to_union(dim);
+ boolean serial_execution = true;
+ if (serial_execution) {
+ if (batch_to_union.size() != 0) {
+ Geometry geomRes = TopologicalOperations
+ .dissolveDirty(batch_to_union,
+ m_spatial_reference,
+ m_progress_tracker);
+ add_geom(dim, true, geomRes);
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return m_b_done;
+ }
+
+ ArrayList collect_geometries_to_union(int dim) {
+ ArrayList batch_to_union = new ArrayList();
+ ArrayList> entriesToRemove = new ArrayList>();
+ Set> set = m_union_bins.get(dim)
+ .entrySet();
+ for (Map.Entry e : set) {
+ //int level = e.getKey();
+ Bin_type bin = e.getValue();
+
+ final int binVertexThreshold = 10000;
+
+ if (m_b_done
+ || (bin.bin_vertex_count > binVertexThreshold && bin
+ .geom_count() > 1)) {
+ m_dim_geom_counts[dim] -= bin.geom_count();
+ m_added_geoms -= bin.geom_count();
+ while (bin.geometries.size() > 0) {
+ // empty geometries will be unioned too.
+ batch_to_union.add(bin.back_pair().geom);
+ bin.pop_pair();
+ }
+
+ entriesToRemove.add(e);
+ }
+ }
+
+ set.removeAll(entriesToRemove);
+ return batch_to_union;
+ }
+
+ private void remove_all_bins_with_lower_dimension(int dim) {
+ // this geometry has higher dimension than the previously processed one
+ for (int i = 0; i < dim; i++) {
+ m_union_bins.get(i).clear();
+ m_added_geoms -= m_dim_geom_counts[i];
+ m_dim_geom_counts[i] = 0;
+ }
+ }
+
+ private void add_geom(int dimension, boolean unioned, Geometry geom) {
+ Geom_pair pair = new Geom_pair();
+ pair.init();
+ pair.geom = geom;
+ int sz = get_vertex_count_(geom);
+ pair.vertex_count = sz;
+ int level = get_level_(sz);
+ if (dimension + 1 > (int) m_union_bins.size()) {
+ for (int i = 0, n = Math.max(2, dimension + 1); i < n; i++) {
+ m_union_bins.add(new TreeMap());
+ }
+ }
+
+ Bin_type bin = m_union_bins.get(dimension).get(level);//return null if level is abscent
+ if (bin == null) {
+ bin = new Bin_type();
+ m_union_bins.get(dimension).put(level, bin);
+ }
+
+ pair.unioned = unioned;
+ bin.add_pair(pair);
+
+ // Update global cursor state
+ m_dim_geom_counts[dimension]++;
+ m_added_geoms++;
+ m_max_dimension = Math.max(m_max_dimension, dimension);
+ }
+
+ private static int get_level_(int sz) {// calculates logarithm of sz to base
+ // 4.
+ return sz > 0 ? (int) (Math.log((double) sz) / Math.log(4.0) + 0.5)
+ : (int) 0;
+ }
+
+ private static int get_vertex_count_(Geometry geom) {
+ int gt = geom.getType().value();
+ if (Geometry.isMultiVertex(gt)) {
+ return ((MultiVertexGeometry) geom).getPointCount();
+ } else if (gt == Geometry.GeometryType.Point) {
+ return 1;
+ } else if (gt == Geometry.GeometryType.Envelope) {
+ return 4;
+ } else if (Geometry.isSegment(gt)) {
+ return 2;
+ } else {
+ throw GeometryException.GeometryInternalError();
+ }
+ }
+
+ @Override
+ public boolean tock() {
+ return step_();
+ }
+}
diff --git a/src/com/esri/core/geometry/OperatorUnionLocal.java b/src/main/java/com/esri/core/geometry/OperatorUnionLocal.java
similarity index 98%
rename from src/com/esri/core/geometry/OperatorUnionLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorUnionLocal.java
index e3cf5ea7..1b723282 100644
--- a/src/com/esri/core/geometry/OperatorUnionLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorUnionLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorWithin.java b/src/main/java/com/esri/core/geometry/OperatorWithin.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorWithin.java
rename to src/main/java/com/esri/core/geometry/OperatorWithin.java
index 9032718f..00a0c15f 100644
--- a/src/com/esri/core/geometry/OperatorWithin.java
+++ b/src/main/java/com/esri/core/geometry/OperatorWithin.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/OperatorWithinLocal.java b/src/main/java/com/esri/core/geometry/OperatorWithinLocal.java
similarity index 97%
rename from src/com/esri/core/geometry/OperatorWithinLocal.java
rename to src/main/java/com/esri/core/geometry/OperatorWithinLocal.java
index 9958ff90..a370a8fe 100644
--- a/src/com/esri/core/geometry/OperatorWithinLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorWithinLocal.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/PairwiseIntersectorImpl.java b/src/main/java/com/esri/core/geometry/PairwiseIntersectorImpl.java
new file mode 100644
index 00000000..d02cc4fa
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/PairwiseIntersectorImpl.java
@@ -0,0 +1,249 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+class PairwiseIntersectorImpl {
+ // Quad_tree
+ private MultiPathImpl m_multi_path_impl_a;
+ private MultiPathImpl m_multi_path_impl_b;
+ private boolean m_b_paths;
+ private boolean m_b_quad_tree;
+ private boolean m_b_done;
+ private boolean m_b_swap_elements;
+ private double m_tolerance;
+ private int m_path_index;
+ private int m_element_handle;
+ private Envelope2D m_paths_query = new Envelope2D(); // only used for m_b_paths == true case
+ private QuadTreeImpl m_quad_tree;
+ private QuadTreeImpl.QuadTreeIteratorImpl m_qt_iter;
+ private SegmentIteratorImpl m_seg_iter;
+
+ // Envelope_2D_intersector
+ private Envelope2DIntersectorImpl m_intersector;
+
+ private int m_function;
+
+ private interface State {
+ static final int nextPath = 0;
+ static final int nextSegment = 1;
+ static final int iterate = 2;
+ }
+
+ PairwiseIntersectorImpl(MultiPathImpl multi_path_impl_a, MultiPathImpl multi_path_impl_b, double tolerance, boolean b_paths) {
+ m_multi_path_impl_a = multi_path_impl_a;
+ m_multi_path_impl_b = multi_path_impl_b;
+
+ m_b_paths = b_paths;
+ m_path_index = -1;
+
+ m_b_quad_tree = false;
+
+ GeometryAccelerators geometry_accelerators_a = multi_path_impl_a._getAccelerators();
+
+ if (geometry_accelerators_a != null) {
+ QuadTreeImpl qtree_a = (!b_paths ? geometry_accelerators_a.getQuadTree() : geometry_accelerators_a.getQuadTreeForPaths());
+
+ if (qtree_a != null) {
+ m_b_done = false;
+ m_tolerance = tolerance;
+ m_quad_tree = qtree_a;
+ m_qt_iter = m_quad_tree.getIterator();
+ m_b_quad_tree = true;
+ m_b_swap_elements = true;
+ m_function = State.nextPath;
+
+ if (!b_paths)
+ m_seg_iter = multi_path_impl_b.querySegmentIterator();
+ else
+ m_path_index = multi_path_impl_b.getPathCount(); // we will iterate backwards until we hit -1
+ }
+ }
+
+ if (!m_b_quad_tree) {
+ GeometryAccelerators geometry_accelerators_b = multi_path_impl_b._getAccelerators();
+
+ if (geometry_accelerators_b != null) {
+ QuadTreeImpl qtree_b = (!b_paths ? geometry_accelerators_b.getQuadTree() : geometry_accelerators_b.getQuadTreeForPaths());
+
+ if (qtree_b != null) {
+ m_b_done = false;
+ m_tolerance = tolerance;
+ m_quad_tree = qtree_b;
+ m_qt_iter = m_quad_tree.getIterator();
+ m_b_quad_tree = true;
+ m_b_swap_elements = false;
+ m_function = State.nextPath;
+
+ if (!b_paths)
+ m_seg_iter = multi_path_impl_a.querySegmentIterator();
+ else
+ m_path_index = multi_path_impl_a.getPathCount(); // we will iterate backwards until we hit -1
+ }
+ }
+ }
+
+ if (!m_b_quad_tree) {
+ if (!b_paths) {
+ m_intersector = InternalUtils.getEnvelope2DIntersector(multi_path_impl_a, multi_path_impl_b, tolerance);
+ } else {
+ boolean b_simple_a = multi_path_impl_a.getIsSimple(0.0) >= 1;
+ boolean b_simple_b = multi_path_impl_b.getIsSimple(0.0) >= 1;
+ m_intersector = InternalUtils.getEnvelope2DIntersectorForParts(multi_path_impl_a, multi_path_impl_b, tolerance, b_simple_a, b_simple_b);
+ }
+ }
+ }
+
+ boolean next() {
+ if (m_b_quad_tree) {
+ if (m_b_done)
+ return false;
+
+ boolean b_searching = true;
+ while (b_searching) {
+ switch (m_function) {
+ case State.nextPath:
+ b_searching = nextPath_();
+ break;
+ case State.nextSegment:
+ b_searching = nextSegment_();
+ break;
+ case State.iterate:
+ b_searching = iterate_();
+ break;
+ default:
+ throw GeometryException.GeometryInternalError();
+ }
+ }
+
+ if (m_b_done)
+ return false;
+
+ return true;
+ }
+
+ if (m_intersector == null)
+ return false;
+
+ return m_intersector.next();
+ }
+
+ int getRedElement() {
+ if (m_b_quad_tree) {
+ if (!m_b_swap_elements)
+ return (!m_b_paths ? m_seg_iter.getStartPointIndex() : m_path_index);
+
+ return m_quad_tree.getElement(m_element_handle);
+ }
+
+ return m_intersector.getRedElement(m_intersector.getHandleA());
+ }
+
+ int getBlueElement() {
+ if (m_b_quad_tree) {
+ if (m_b_swap_elements)
+ return (!m_b_paths ? m_seg_iter.getStartPointIndex() : m_path_index);
+
+ return m_quad_tree.getElement(m_element_handle);
+ }
+
+ return m_intersector.getBlueElement(m_intersector.getHandleB());
+ }
+
+ Envelope2D getRedEnvelope() {
+ if (!m_b_paths)
+ throw GeometryException.GeometryInternalError();
+
+ if (m_b_quad_tree) {
+ if (!m_b_swap_elements)
+ return m_paths_query;
+
+ return m_quad_tree.getElementExtent(m_element_handle);
+ }
+
+ return m_intersector.getRedEnvelope(m_intersector.getHandleA());
+ }
+
+ Envelope2D getBlueEnvelope() {
+ if (!m_b_paths)
+ throw GeometryException.GeometryInternalError();
+
+ if (m_b_quad_tree) {
+ if (m_b_swap_elements)
+ return m_paths_query;
+
+ return m_quad_tree.getElementExtent(m_element_handle);
+ }
+
+ return m_intersector.getBlueEnvelope(m_intersector.getHandleB());
+ }
+
+ boolean nextPath_() {
+ if (!m_b_paths) {
+ if (!m_seg_iter.nextPath()) {
+ m_b_done = true;
+ return false;
+ }
+
+ m_function = State.nextSegment;
+ return true;
+ }
+
+ if (--m_path_index == -1) {
+ m_b_done = true;
+ return false;
+ }
+
+ if (m_b_swap_elements)
+ m_multi_path_impl_b.queryPathEnvelope2D(m_path_index, m_paths_query);
+ else
+ m_multi_path_impl_a.queryPathEnvelope2D(m_path_index, m_paths_query);
+
+ m_qt_iter.resetIterator(m_paths_query, m_tolerance);
+ m_function = State.iterate;
+ return true;
+ }
+
+ boolean nextSegment_() {
+ if (!m_seg_iter.hasNextSegment()) {
+ m_function = State.nextPath;
+ return true;
+ }
+
+ Segment segment = m_seg_iter.nextSegment();
+ m_qt_iter.resetIterator(segment, m_tolerance);
+ m_function = State.iterate;
+ return true;
+ }
+
+ boolean iterate_() {
+ m_element_handle = m_qt_iter.next();
+
+ if (m_element_handle == -1) {
+ m_function = (!m_b_paths ? State.nextSegment : State.nextPath);
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/src/com/esri/core/geometry/PathFlags.java b/src/main/java/com/esri/core/geometry/PathFlags.java
similarity index 98%
rename from src/com/esri/core/geometry/PathFlags.java
rename to src/main/java/com/esri/core/geometry/PathFlags.java
index b163559e..1fa09c35 100644
--- a/src/com/esri/core/geometry/PathFlags.java
+++ b/src/main/java/com/esri/core/geometry/PathFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/PeDouble.java b/src/main/java/com/esri/core/geometry/PeDouble.java
similarity index 97%
rename from src/com/esri/core/geometry/PeDouble.java
rename to src/main/java/com/esri/core/geometry/PeDouble.java
index 90bf9abf..fd33af49 100644
--- a/src/com/esri/core/geometry/PeDouble.java
+++ b/src/main/java/com/esri/core/geometry/PeDouble.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/PlaneSweepCrackerHelper.java b/src/main/java/com/esri/core/geometry/PlaneSweepCrackerHelper.java
similarity index 87%
rename from src/com/esri/core/geometry/PlaneSweepCrackerHelper.java
rename to src/main/java/com/esri/core/geometry/PlaneSweepCrackerHelper.java
index 75e01a50..c84b4724 100644
--- a/src/com/esri/core/geometry/PlaneSweepCrackerHelper.java
+++ b/src/main/java/com/esri/core/geometry/PlaneSweepCrackerHelper.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -60,22 +60,19 @@ boolean sweep(EditShape shape, double tolerance) {
m_b_cracked = false;
m_tolerance = tolerance;
m_tolerance_sqr = tolerance * tolerance;
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // DEBUGPRINTF(L"PlaneSweep along x\n");
- // }
- // #endif
boolean b_cracked = sweepImpl_();
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // DEBUGPRINTF(L"PlaneSweep along y\n");
- // }
- // #endif
shape.applyTransformation(transform);
- fillEventQueuePass2();
- b_cracked |= sweepImpl_();
- m_shape.removeUserIndex(m_vertex_cluster_index);
+ if (!b_cracked) {
+ fillEventQueuePass2();
+ b_cracked |= sweepImpl_();
+ }
+
+ if (m_vertex_cluster_index != -1) {
+ m_shape.removeUserIndex(m_vertex_cluster_index);
+ m_vertex_cluster_index = -1;
+ }
+
m_shape = null;
return m_b_cracked;
}
@@ -89,9 +86,17 @@ boolean sweepVertical(EditShape shape, double tolerance) {
m_complications = false;
boolean bresult = sweepImpl_();
if (!m_complications) {
- int filtered = shape.filterClosePoints(tolerance, true);
+ int filtered = shape.filterClosePoints(tolerance, true, false);
m_complications = filtered == 1;
+ bresult |= filtered == 1;
}
+
+ if (m_vertex_cluster_index != -1) {
+ m_shape.removeUserIndex(m_vertex_cluster_index);
+ m_vertex_cluster_index = -1;
+ }
+
+ m_shape = null;
return bresult;
}
@@ -372,7 +377,7 @@ void addEdgeToCluster(int edge, int cluster) {
assert (getEdgeCluster(edge, 0) != cluster);
setEdgeCluster_(edge, 1, cluster);
} else
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
addEdgeToClusterImpl_(edge, cluster);// simply adds the edge to the list
// of cluster edges.
@@ -527,16 +532,9 @@ void mergeEdges_(int edge1, int edge2) {
// Merged edges have different clusters (clusters have not yet been
// merged)
// merge clusters before merging the edges
- Point2D pt11 = getClusterXY(cluster_1);
- Point2D pt21 = getClusterXY(cluster21);
- // #ifdef _DEBUG_TOPO
- // Point_2D pt12, pt22;
- // pt12 = get_cluster_xy(cluster2);
- // pt22 = get_cluster_xy(cluster22);
- // assert((pt11.is_equal(pt21) && pt12.is_equal(pt22)) ||
- // (pt12.is_equal(pt21) && pt11.is_equal(pt22)));
- // #endif
- if (pt11.isEqual(pt21)) {
+ getClusterXY(cluster_1, pt_1);
+ getClusterXY(cluster21, pt_2);
+ if (pt_1.isEqual(pt_2)) {
if (cluster_1 != cluster21) {
mergeClusters_(cluster_1, cluster21);
assert (!m_modified_clusters.hasElement(cluster21));
@@ -772,21 +770,31 @@ int compare(Treap treap, int node) {
void processSplitHelper1_(int index, int edge,
SegmentIntersector intersector) {
+ int clusterStart = getEdgeCluster(edge, 0);
+ Point2D ptClusterStart = new Point2D();
+ getClusterXY(clusterStart, ptClusterStart);
+ Point2D ptClusterEnd = new Point2D();
+ int clusterEnd = getEdgeCluster(edge, 1);
+ getClusterXY(clusterEnd, ptClusterEnd);
+
// Collect all edges that are affected by the split and that are in the
// sweep structure.
int count = intersector.getResultSegmentCount(index);
Segment seg = intersector.getResultSegment(index, 0);
- Point2D newStart = seg.getStartXY();
- int clusterStart = getEdgeCluster(edge, 0);
- Point2D pt = getClusterXY(clusterStart);
- if (!pt.isEqual(newStart)) {
- if (pt.compare(m_sweep_point) > 0
- && newStart.compare(m_sweep_point) < 0) {
- m_complications = true;// point is not yet have been processed
- // but moved before the sweep point,
- // this will require
- // repeating the cracking step and the sweep_vertical cannot
- // help here
+ Point2D newStart = new Point2D();
+ seg.getStartXY(newStart);
+
+ if (!ptClusterStart.isEqual(newStart)) {
+ if (!m_complications) {
+ int res1 = ptClusterStart.compare(m_sweep_point);
+ int res2 = newStart.compare(m_sweep_point);
+ if (res1 * res2 < 0) {
+ m_complications = true;// point is not yet have been processed
+ // but moved before the sweep point,
+ // this will require
+ // repeating the cracking step and the sweep_vertical cannot
+ // help here
+ }
}
// This cluster's position needs to be changed
@@ -794,17 +802,37 @@ void processSplitHelper1_(int index, int edge,
m_modified_clusters.add(clusterStart);
}
+ if (!m_complications && count > 1) {
+ int dir = ptClusterStart.compare(ptClusterEnd);
+ Point2D midPoint = seg.getEndXY();
+ if (ptClusterStart.compare(midPoint) != dir
+ || midPoint.compare(ptClusterEnd) != dir) {// split segment
+ // midpoint is
+ // above the
+ // sweep line.
+ // Therefore the
+ // part of the
+ // segment
+ m_complications = true;
+ } else {
+ if (midPoint.compare(m_sweep_point) < 0) {
+ // midpoint moved below sweepline.
+ m_complications = true;
+ }
+ }
+ }
+
seg = intersector.getResultSegment(index, count - 1);
Point2D newEnd = seg.getEndXY();
- int clusterEnd = getEdgeCluster(edge, 1);
- pt = getClusterXY(clusterEnd);
- if (!pt.isEqual(newEnd)) {
- if (pt.compare(m_sweep_point) > 0
- && newEnd.compare(m_sweep_point) < 0) {
- m_complications = true;// point is not yet have been processed
- // but moved before the sweep point.
+ if (!ptClusterEnd.isEqual(newEnd)) {
+ if (!m_complications) {
+ int res1 = ptClusterEnd.compare(m_sweep_point);
+ int res2 = newEnd.compare(m_sweep_point);
+ if (res1 * res2 < 0) {
+ m_complications = true;// point is not yet have been processed
+ // but moved before the sweep point.
+ }
}
-
// This cluster's position needs to be changed
getAffectedEdges(clusterEnd, m_temp_edge_buffer);
m_modified_clusters.add(clusterEnd);
@@ -846,8 +874,6 @@ boolean checkAndFixIntersection_(int leftSweepNode, int rightSweepNode) {
}
void fixIntersection_(int left, int right) {
- // static int dbg = 0;
- // dbg++;
m_b_cracked = true;
int edge1 = m_sweep_structure.getElement(left);
int edge2 = m_sweep_structure.getElement(right);
@@ -893,24 +919,6 @@ void fixIntersection_(int left, int right) {
m_complications = true;
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // for (int resi = 0; resi < 2; resi++)
- // {
- // DEBUGPRINTF(L"intersection result %d:\n", resi);
- // for (int i = 0; i <
- // m_segment_intersector.get_result_segment_count(resi); i++)
- // {
- // Point_2D pt_1 = m_segment_intersector.get_result_segment(resi,
- // i)->get_start_xy();
- // Point_2D pt_2 = m_segment_intersector.get_result_segment(resi,
- // i)->get_end_xy();
- // DEBUGPRINTF(L"(%0.17f, %0.17f --- %0.17f, %0.17f)\n", pt_1.x,
- // pt_1.y, pt_2.x, pt_2.y);
- // }
- // }
- // }
- // #endif
splitEdge_(edge1, edge2, -1, m_segment_intersector);
m_segment_intersector.clear();
}
@@ -929,38 +937,13 @@ void fixIntersectionPointSegment_(int cluster, int node) {
seg_1 = m_line_1;
}
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // Point_2D pt11, pt12, pt21;
- // pt11 = seg_1->get_start_xy();
- // pt12 = seg_1->get_end_xy();
- // get_cluster_xy(cluster, pt21);
- // DEBUGPRINTF(L"Intersecting edge %d (%0.4f, %0.4f - %0.4f, %0.4f) and cluster %d (%0.4f, %0.4f)\n",
- // edge1, pt11.x, pt11.y, pt12.x, pt12.y, cluster, pt21.x, pt21.y);
- // }
- // #endif
-
int clusterVertex = getClusterFirstVertex(cluster);
m_segment_intersector.pushSegment(seg_1);
m_shape.queryPoint(clusterVertex, m_helper_point);
m_segment_intersector.intersect(m_tolerance, m_helper_point, 0, 1.0,
true);
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // DEBUGPRINTF(L"intersection result\n");
- // for (int i = 0; i <
- // m_segment_intersector.get_result_segment_count(0); i++)
- // {
- // Point_2D pt_1 = m_segment_intersector.get_result_segment(0,
- // i)->get_start_xy();
- // Point_2D pt_2 = m_segment_intersector.get_result_segment(0,
- // i)->get_end_xy();
- // DEBUGPRINTF(L"(%0.17f, %0.17f --- %0.17f, %0.17f)\n", pt_1.x,
- // pt_1.y, pt_2.x, pt_2.y);
- // }
- // }
- // #endif
+
splitEdge_(edge1, -1, cluster, m_segment_intersector);
m_segment_intersector.clear();
@@ -970,8 +953,6 @@ void insertNewEdges_() {
if (m_edges_to_insert_in_sweep_structure.size() == 0)
return;
- // dbg_check_new_edges_array_();
-
while (m_edges_to_insert_in_sweep_structure.size() != 0) {
if (m_edges_to_insert_in_sweep_structure.size() > Math.max(
(int) 100, m_shape.getTotalPointCount())) {
@@ -983,10 +964,8 @@ void insertNewEdges_() {
// iterate on the data one more time.
}
- int edge = m_edges_to_insert_in_sweep_structure
- .get(m_edges_to_insert_in_sweep_structure.size() - 1);
- m_edges_to_insert_in_sweep_structure
- .resize(m_edges_to_insert_in_sweep_structure.size() - 1);
+ int edge = m_edges_to_insert_in_sweep_structure.getLast();
+ m_edges_to_insert_in_sweep_structure.removeLast();
assert (getEdgeSweepNode(edge) == StridedIndexTypeCollection
.impossibleIndex3());
@@ -1001,37 +980,18 @@ void insertNewEdges_() {
boolean insertNewEdgeToSweepStructure_(int edge, int terminatingCluster) {
assert (getEdgeSweepNode(edge) == -1);
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // Point_2D pt11, pt12;
- // int c_1 = get_edge_cluster(edge, 0);
- // int c_2 = get_edge_cluster(edge, 1);
- // get_cluster_xy(c_1, pt11);
- // get_cluster_xy(c_2, pt12);
- // DEBUGPRINTF(L"Inserting edge %d (%0.4f, %0.4f - %0.4f, %0.4f) to sweep structure\n",
- // edge, pt11.x, pt11.y, pt12.x, pt12.y);
- // }
- // #endif
int newEdgeNode;
if (m_b_continuing_segment_chain_optimization) {
- // st_counter_insertions++;
- // st_counter_insertions_optimized++;
newEdgeNode = m_sweep_structure.addElementAtPosition(
m_prev_neighbour, m_next_neighbour, edge, true, true, -1);
m_b_continuing_segment_chain_optimization = false;
} else {
- // st_counter_insertions++;
- // st_counter_insertions_unique++;
newEdgeNode = m_sweep_structure.addUniqueElement(edge, -1);
}
if (newEdgeNode == -1) {// a coinciding edge.
int existingNode = m_sweep_structure.getDuplicateElement(-1);
int existingEdge = m_sweep_structure.getElement(existingNode);
- // #ifdef _DEBUG_CRACKING_REPORT
- // DEBUGPRINTF(L"Edge %d is a duplicate of %d. Merged\n", edge,
- // existingEdge);
- // #endif
mergeEdges_(existingEdge, edge);
return false;
}
@@ -1040,10 +1000,6 @@ boolean insertNewEdgeToSweepStructure_(int edge, int terminatingCluster) {
setEdgeSweepNode_(edge, newEdgeNode);
if (m_sweep_comparator.intersectionDetected()) {
- // #ifdef _DEBUG_CRACKING_REPORT
- // DEBUGPRINTF(L"intersection detected\n");
- // #endif
-
// The edge has been inserted into the sweep structure and an
// intersection has beebn found. The edge will be split and removed.
m_sweep_comparator.clearIntersectionDetectedFlag();
@@ -1058,11 +1014,13 @@ boolean insertNewEdgeToSweepStructure_(int edge, int terminatingCluster) {
return false;
}
+ Point2D pt_1 = new Point2D();
+ Point2D pt_2 = new Point2D();
int isEdgeOnSweepLine_(int edge) {
int cluster_1 = getEdgeCluster(edge, 0);
int cluster2 = getEdgeCluster(edge, 1);
- Point2D pt_1 = getClusterXY(cluster_1);
- Point2D pt_2 = getClusterXY(cluster2);
+ getClusterXY(cluster_1, pt_1);
+ getClusterXY(cluster2, pt_2);
if (Point2D.sqrDistance(pt_1, pt_2) <= m_tolerance_sqr) {// avoid
// degenerate
// segments
@@ -1091,18 +1049,14 @@ void fillEventQueue() {
// clusters
EditShape.VertexIterator iter = m_shape.queryVertexIterator();
for (int vert = iter.next(); vert != -1; vert = iter.next()) {
- event_q.add(vert);
+ if (m_shape.getUserIndex(vert, m_vertex_cluster_index) != -1)
+ event_q.add(vert);
}
- assert (m_shape.getTotalPointCount() == event_q.size());
-
// Now we can merge coincident clusters and form the envent structure.
// sort vertices lexicographically.
m_shape.sortVerticesSimpleByY_(event_q, 0, event_q.size());
- // int perPoint = m_shape->estimate_memory_size() /
- // m_shape->get_total_point_count();
- // perPoint = 0;
// The m_event_q is the event structure for the planesweep algorithm.
// We could use any data structure that allows log(n) insertion and
@@ -1123,9 +1077,10 @@ void fillEventQueue() {
Point2D cluster_pt = new Point2D();
cluster_pt.setNaN();
int cluster = -1;
+ Point2D pt = new Point2D();
for (int index = 0, nvertex = event_q.size(); index < nvertex; index++) {
int vertex = event_q.get(index);
- Point2D pt = m_shape.getXY(vertex);
+ m_shape.getXY(vertex, pt);
if (pt.isEqual(cluster_pt)) {
int vertexCluster = m_shape.getUserIndex(vertex,
m_vertex_cluster_index);
@@ -1135,7 +1090,7 @@ void fillEventQueue() {
cluster = getClusterFromVertex(vertex);
// add a vertex to the event queue
- cluster_pt = m_shape.getXY(vertex);
+ m_shape.getXY(vertex, cluster_pt);
int eventQnode = m_event_q.addBiggestElement(vertex, -1); // this
// method
// does
@@ -1218,18 +1173,6 @@ void updateClusterXY(int cluster, Point2D pt) {
// m_edges_to_insert_in_sweep_structure.
void splitEdge_(int edge1, int edge2, int intersectionCluster,
SegmentIntersector intersector) {
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // if (edge2 != -1)
- // DEBUGPRINTF(L"Splitting edge1 (%d) and edge2 (%d)\n", edge1, edge2);
- // else
- // DEBUGPRINTF(L"Splitting edge (%d)\n", edge1);
- // }
- // #endif
- // dbg_check_edge_(edge1);
- //
- // if (edge2 != -1)
- // dbg_check_edge_(edge2);
disconnectEdge_(edge1);// disconnects the edge from the clusters. The
// edge still remembers the clusters.
@@ -1246,9 +1189,9 @@ void splitEdge_(int edge1, int edge2, int intersectionCluster,
processSplitHelper1_(1, edge2, intersector);
if (intersectionCluster != -1) {
- Point2D pt = intersector.getResultPoint().getXY();
- Point2D ptCluster = getClusterXY(intersectionCluster);
- if (!ptCluster.isEqual(pt))
+ intersector.getResultPoint().getXY(pt_1);
+ getClusterXY(intersectionCluster, pt_2);
+ if (!pt_2.isEqual(pt_1))
m_modified_clusters.add(intersectionCluster);
}
@@ -1269,9 +1212,14 @@ void splitEdge_(int edge1, int edge2, int intersectionCluster,
// Adjust the vertex coordinates and split the segments in the the edit
// shape.
applyIntersectorToEditShape_(edgeOrigins1, intersector, 0);
- if (edge2 != -1)
+ if (edgeOrigins2 != -1)
applyIntersectorToEditShape_(edgeOrigins2, intersector, 1);
-
+ else {
+ assert (intersectionCluster != -1);
+ Point2D pt = intersector.getResultPoint().getXY();
+ updateClusterXY(intersectionCluster, pt);
+ }
+
// Produce clusters, and new edges. The new edges are added to
// m_edges_to_insert_in_sweep_structure.
createEdgesAndClustersFromSplitEdge_(edge1, intersector, 0);
@@ -1298,17 +1246,6 @@ void splitEdge_(int edge1, int edge2, int intersectionCluster,
int vertex = getClusterFirstVertex(cluster);
assert (getClusterFromVertex(vertex) == cluster);
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // Point_2D pt;
- // m_shape->get_xy(vertex, pt);
- // DEBUGPRINTF(L"Inserting vertex %d, cluster %d (%0.3f, %0.3f)\n",
- // vertex, cluster, pt.x, pt.y);
- // }
- // #endif
- // st_counter_insertions++;
- // st_counter_insertions_unique++;
-
eventQnode = m_event_q.addUniqueElement(vertex, -1);// O(logN)
// operation
if (eventQnode == -1) {// the cluster is coinciding with another
@@ -1317,17 +1254,10 @@ void splitEdge_(int edge1, int edge2, int intersectionCluster,
int v = m_event_q.getElement(existingNode);
assert (m_shape.isEqualXY(vertex, v));
int existingCluster = getClusterFromVertex(v);
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // Point_2D pt;
- // m_shape->get_xy(v, pt);
- // DEBUGPRINTF(L"Already in the queue %d, cluster %d (%0.3f, %0.3f)\n",
- // v, existingCluster, pt.x, pt.y);
- // }
- // #endif
mergeClusters_(existingCluster, cluster);
- } else
+ } else {
setClusterEventQNode_(cluster, eventQnode);
+ }
} else {
// if already inserted (probably impossible) case
}
@@ -1337,11 +1267,9 @@ void splitEdge_(int edge1, int edge2, int intersectionCluster,
}
// Returns a cluster's xy.
- Point2D getClusterXY(int cluster) {
- Point2D p = new Point2D();
+ void getClusterXY(int cluster, Point2D ptOut) {
int vindex = getClusterVertexIndex(cluster);
- m_shape.getXYWithIndex(vindex, p);
- return p;
+ m_shape.getXYWithIndex(vindex, ptOut);
}
int getClusterFirstVertex(int cluster) {
@@ -1379,12 +1307,6 @@ boolean sweepImpl_() {
int vertex = m_event_q.getElement(eventQnode);
m_sweep_point_cluster = getClusterFromVertex(vertex);
m_shape.getXY(vertex, m_sweep_point);
- // #ifdef _DEBUG_CRACKING_REPORT
- // {
- // DEBUGPRINTF(L"next event node. Cluster %d, Vertex %d, (%0.3f, %0.3f)\n",
- // m_sweep_point_cluster, vertex, m_sweep_point.x, m_sweep_point.y);
- // }
- // #endif
m_sweep_comparator.setSweepY(m_sweep_point.y, m_sweep_point.x);// move
// the
@@ -1404,7 +1326,7 @@ boolean sweepImpl_() {
setEdgeSweepNode_(edge, c_3);// mark that its in
// m_edges_to_insert_in_sweep_structure
} else if (sweepNode != c_3) {
- // assert(StridedIndexTypeCollection.isValidElement(sweepNode));
+ assert(StridedIndexTypeCollection.isValidElement(sweepNode));
edgesToDelete.add(sweepNode);
}
edge = getNextEdge(edge, m_sweep_point_cluster);
@@ -1423,8 +1345,6 @@ boolean sweepImpl_() {
m_b_continuing_segment_chain_optimization = (edgesToDelete
.size() == 1 && m_edges_to_insert_in_sweep_structure
.size() == 1);
- // st_counter_insertions_all_potential +=
- // m_edges_to_insert_in_sweep_structure.size() > 0;
// Mark nodes that need to be deleted by setting c_2 to the
// edge's sweep node member.
@@ -1482,11 +1402,9 @@ boolean sweepImpl_() {
// Now check if the left and right we found intersect or not.
if (left != -1 && right != -1) {
- boolean bIntersected = checkAndFixIntersection_(left, right);
- if (bIntersected) {
- // We'll insert the results of intersection below in
- // insert_new_edges_
- m_b_continuing_segment_chain_optimization = false;
+ if (!m_b_continuing_segment_chain_optimization) {
+ boolean bIntersected = checkAndFixIntersection_(left,
+ right);
}
} else {
if ((left == -1) && (right == -1))
@@ -1568,12 +1486,6 @@ void setEditShape_(EditShape shape) {
int path_size = m_shape.getPathSize(path);
assert (path_size > 1);
int first_vertex = m_shape.getFirstVertex(path);
- // #ifdef _DEBUG_TOPO
- // LOCALREFCLASS(Line, line);
- // m_shape.query_line_connector(first_vertex, line);
- // assert(line.calculate_length_2D() > m_tolerance);//no
- // degenerate lines at the input
- // #endif
// first------------------
int firstCluster = newCluster_(first_vertex);
@@ -1582,24 +1494,31 @@ void setEditShape_(EditShape shape) {
int prevEdge = first_edge;
int vertex = m_shape.getNextVertex(first_vertex);
for (int index = 0, n = path_size - 2; index < n; index++) {
+ int nextvertex = m_shape.getNextVertex(vertex);
// ------------x------------
int cluster = newCluster_(vertex);
addEdgeToCluster(prevEdge, cluster);
int newEdge = newEdge_(vertex);
addEdgeToCluster(newEdge, cluster);
prevEdge = newEdge;
- vertex = m_shape.getNextVertex(vertex);
+ vertex = nextvertex;
}
// ------------------lastx
- int cluster = newCluster_(vertex);
- addEdgeToCluster(prevEdge, cluster);
- if (m_shape.isClosedPath(path)) {// close the path
- // lastx------------------firstx
+ if (m_shape.isClosedPath(path)) {
+ int cluster = newCluster_(vertex);
+ addEdgeToCluster(prevEdge, cluster);
+ // close the path
+ // lastx------------------firstx
int newEdge = newEdge_(vertex);
addEdgeToCluster(newEdge, cluster);
addEdgeToCluster(newEdge, firstCluster);
+ } else {
+ // ------------------lastx
+ int cluster = newCluster_(vertex);
+ addEdgeToCluster(prevEdge, cluster);
}
+
}
}
diff --git a/src/com/esri/core/geometry/Point.java b/src/main/java/com/esri/core/geometry/Point.java
similarity index 61%
rename from src/com/esri/core/geometry/Point.java
rename to src/main/java/com/esri/core/geometry/Point.java
index ea4c02c7..cc5b7042 100644
--- a/src/com/esri/core/geometry/Point.java
+++ b/src/main/java/com/esri/core/geometry/Point.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,31 +25,38 @@
package com.esri.core.geometry;
import com.esri.core.geometry.VertexDescription.Semantics;
+
import java.io.Serializable;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_POINT;
+
/**
* A Point is a zero-dimensional object that represents a specific (X,Y)
* location in a two-dimensional XY-Plane. In case of Geographic Coordinate
* Systems, the X coordinate is the longitude and the Y is the latitude.
*/
-public final class Point extends Geometry implements Serializable {
- private static final long serialVersionUID = 2L;// TODO:remove as we use
- // writeReplace and
- // GeometrySerializer
+public class Point extends Geometry implements Serializable {
+ //We are using writeReplace instead.
+ //private static final long serialVersionUID = 2L;
- double[] m_attributes; // use doubles to store everything (long are bitcast)
+ private double m_x;
+ private double m_y;
+ private double[] m_attributes; // use doubles to store everything (long are bitcast)
/**
* Creates an empty 2D point.
*/
public Point() {
m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
+ m_x = NumberUtils.TheNaN;
+ m_y = NumberUtils.TheNaN;
}
- Point(VertexDescription vd) {
+ public Point(VertexDescription vd) {
if (vd == null)
throw new IllegalArgumentException();
m_description = vd;
+ _setToDefault();
}
/**
@@ -66,6 +73,11 @@ public Point(double x, double y) {
m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
setXY(x, y);
}
+
+ public Point(Point2D pt) {
+ m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
+ setXY(pt);
+ }
/**
* Creates a 3D point with specified X, Y and Z coordinates. In case of
@@ -85,27 +97,29 @@ public Point(double x, double y, double z) {
Point3D pt = new Point3D();
pt.setCoords(x, y, z);
setXYZ(pt);
-
}
/**
* Returns XY coordinates of this point.
*/
- Point2D getXY() {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation should not be performed on an empty geometry.");
-
+ public final Point2D getXY() {
Point2D pt = new Point2D();
- pt.setCoords(m_attributes[0], m_attributes[1]);
+ pt.setCoords(m_x, m_y);
return pt;
}
+ /**
+ * Returns XY coordinates of this point.
+ */
+ public final void getXY(Point2D pt) {
+ pt.setCoords(m_x, m_y);
+ }
+
/**
* Sets the XY coordinates of this point. param pt The point to create the X
* and Y coordinate from.
*/
- void setXY(Point2D pt) {
+ public final void setXY(Point2D pt) {
_touch();
setXY(pt.x, pt.y);
}
@@ -113,18 +127,11 @@ void setXY(Point2D pt) {
/**
* Returns XYZ coordinates of the point. Z will be set to 0 if Z is missing.
*/
- Point3D getXYZ() {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation should not be performed on an empty geometry.");
-
+ public Point3D getXYZ() {
Point3D pt = new Point3D();
- pt.x = m_attributes[0];
- pt.y = m_attributes[1];
- if (m_description.hasZ())
- pt.z = m_attributes[2];
- else
- pt.z = VertexDescription.getDefaultValue(Semantics.Z);
+ pt.x = m_x;
+ pt.y = m_y;
+ pt.z = hasZ() ? m_attributes[0] : VertexDescription.getDefaultValue(VertexDescription.Semantics.Z);
return pt;
}
@@ -135,41 +142,19 @@ Point3D getXYZ() {
* @param pt
* The point to create the XYZ coordinate from.
*/
- void setXYZ(Point3D pt) {
+ public void setXYZ(Point3D pt) {
_touch();
- boolean bHasZ = hasAttribute(Semantics.Z);
- if (!bHasZ && !VertexDescription.isDefaultValue(Semantics.Z, pt.z)) {// add
- // Z
- // only
- // if
- // pt.z
- // is
- // not
- // a
- // default
- // value.
- addAttribute(Semantics.Z);
- bHasZ = true;
- }
-
- if (m_attributes == null)
- _setToDefault();
-
- m_attributes[0] = pt.x;
- m_attributes[1] = pt.y;
- if (bHasZ)
- m_attributes[2] = pt.z;
+ addAttribute(Semantics.Z);
+ m_x = pt.x;
+ m_y = pt.y;
+ m_attributes[0] = pt.z;
}
/**
* Returns the X coordinate of the point.
*/
public final double getX() {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation should not be performed on an empty geometry.");
-
- return m_attributes[0];
+ return m_x;
}
/**
@@ -179,18 +164,14 @@ public final double getX() {
* The X coordinate to be set for this point.
*/
public void setX(double x) {
- setAttribute(Semantics.POSITION, 0, x);
+ m_x = x;
}
/**
* Returns the Y coordinate of this point.
*/
public final double getY() {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation should not be performed on an empty geometry.");
-
- return m_attributes[1];
+ return m_y;
}
/**
@@ -200,14 +181,14 @@ public final double getY() {
* The Y coordinate to be set for this point.
*/
public void setY(double y) {
- setAttribute(Semantics.POSITION, 1, y);
+ m_y = y;
}
/**
* Returns the Z coordinate of this point.
*/
public double getZ() {
- return getAttributeAsDbl(Semantics.Z, 0);
+ return hasZ() ? m_attributes[0] : VertexDescription.getDefaultValue(VertexDescription.Semantics.Z);
}
/**
@@ -265,10 +246,18 @@ public void setID(int id) {
* @return The ordinate as double value.
*/
public double getAttributeAsDbl(int semantics, int ordinate) {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation was performed on an Empty Geometry.");
-
+ if (semantics == VertexDescription.Semantics.POSITION) {
+ if (ordinate == 0) {
+ return m_x;
+ }
+ else if (ordinate == 1) {
+ return m_y;
+ }
+ else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
int ncomps = VertexDescription.getComponentCount(semantics);
if (ordinate >= ncomps)
throw new IndexOutOfBoundsException();
@@ -276,7 +265,7 @@ public double getAttributeAsDbl(int semantics, int ordinate) {
int attributeIndex = m_description.getAttributeIndex(semantics);
if (attributeIndex >= 0)
return m_attributes[m_description
- ._getPointAttributeOffset(attributeIndex) + ordinate];
+ ._getPointAttributeOffset(attributeIndex) - 2 + ordinate];
else
return VertexDescription.getDefaultValue(semantics);
}
@@ -293,20 +282,7 @@ public double getAttributeAsDbl(int semantics, int ordinate) {
* @return The ordinate value truncated to a 32 bit integer value.
*/
public int getAttributeAsInt(int semantics, int ordinate) {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation was performed on an Empty Geometry.");
-
- int ncomps = VertexDescription.getComponentCount(semantics);
- if (ordinate >= ncomps)
- throw new IndexOutOfBoundsException();
-
- int attributeIndex = m_description.getAttributeIndex(semantics);
- if (attributeIndex >= 0)
- return (int) m_attributes[m_description
- ._getPointAttributeOffset(attributeIndex) + ordinate];
- else
- return (int) VertexDescription.getDefaultValue(semantics);
+ return (int)getAttributeAsDbl(semantics, ordinate);
}
/**
@@ -323,6 +299,19 @@ public int getAttributeAsInt(int semantics, int ordinate) {
*/
public void setAttribute(int semantics, int ordinate, double value) {
_touch();
+ if (semantics == VertexDescription.Semantics.POSITION) {
+ if (ordinate == 0) {
+ m_x = value;
+ }
+ else if (ordinate == 1) {
+ m_y = value;
+ }
+ else {
+ throw new IndexOutOfBoundsException();
+ }
+ return;
+ }
+
int ncomps = VertexDescription.getComponentCount(semantics);
if (ncomps < ordinate)
throw new IndexOutOfBoundsException();
@@ -333,10 +322,7 @@ public void setAttribute(int semantics, int ordinate, double value) {
attributeIndex = m_description.getAttributeIndex(semantics);
}
- if (m_attributes == null)
- _setToDefault();
-
- m_attributes[m_description._getPointAttributeOffset(attributeIndex)
+ m_attributes[m_description._getPointAttributeOffset(attributeIndex) - 2
+ ordinate] = value;
}
@@ -355,61 +341,78 @@ public int getDimension() {
}
@Override
- public void setEmpty() {
- _touch();
- if (m_attributes != null) {
- m_attributes[0] = NumberUtils.NaN();
- m_attributes[1] = NumberUtils.NaN();
- }
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_POINT + estimateMemorySize(m_attributes);
}
@Override
- void _afterAddAttributeImpl(int semantics) {
+ public void setEmpty() {
_touch();
- if (m_attributes == null)
- return;
-
- int attributeIndex = m_description.getAttributeIndex(semantics);
- int offset = m_description._getPointAttributeOffset(attributeIndex);
- int comps = VertexDescription.getComponentCount(semantics);
- int totalComps = m_description._getTotalComponents();
- resizeAttributes(totalComps);
-
- for (int i = totalComps - 1; i >= offset + comps; i--)
- m_attributes[i] = m_attributes[i - comps];
-
- double dv = VertexDescription.getDefaultValue(semantics);
- for (int i = 0; i < comps; i++)
- m_attributes[offset + i] = dv;
+ _setToDefault();
}
@Override
- void _beforeDropAttributeImpl(int semantics) {
- _touch();
- if (m_attributes == null)
- return;
-
- // _ASSERT(semantics != enum_value2(VertexDescription, Semantics,
- // POSITION));
- int attributeIndex = m_description.getAttributeIndex(semantics);
- int offset = m_description._getPointAttributeOffset(attributeIndex);
- int comps = VertexDescription.getComponentCount(semantics);
- int totalCompsOld = m_description._getTotalComponents();
- if (totalCompsOld > comps) {
- for (int i = offset + comps; i < totalCompsOld; i++)
- m_attributes[i - comps] = m_attributes[i];
+ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
+ int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);
+
+ int newLen = newDescription.getTotalComponentCount() - 2;
+ if (newLen > 0) {
+ double[] newAttributes = new double[newLen];
+
+ int j = 0;
+ for (int i = 1, n = newDescription.getAttributeCount(); i < n; i++) {
+ int semantics = newDescription.getSemantics(i);
+ int nords = VertexDescription.getComponentCount(semantics);
+ if (mapping[i] == -1)
+ {
+ double d = VertexDescription.getDefaultValue(semantics);
+ for (int ord = 0; ord < nords; ord++)
+ {
+ newAttributes[j] = d;
+ j++;
+ }
+ }
+ else {
+ int m = mapping[i];
+ int offset = m_description._getPointAttributeOffset(m) - 2;
+ for (int ord = 0; ord < nords; ord++)
+ {
+ newAttributes[j] = m_attributes[offset];
+ j++;
+ offset++;
+ }
+ }
+
+ }
+
+ m_attributes = newAttributes;
+ }
+ else {
+ m_attributes = null;
}
+
+ m_description = newDescription;
}
/**
- * Sets the Point to a default, non-empty state.
+ * Sets to a default empty state.
*/
- void _setToDefault() {
- resizeAttributes(m_description._getTotalComponents());
- Point.attributeCopy(m_description._getDefaultPointAttributes(),
- m_attributes, m_description._getTotalComponents());
- m_attributes[0] = NumberUtils.NaN();
- m_attributes[1] = NumberUtils.NaN();
+ private void _setToDefault() {
+ int len = m_description.getTotalComponentCount() - 2;
+ if (len != 0) {
+ if (m_attributes == null || m_attributes.length != len) {
+ m_attributes = new double[len];
+ }
+
+ System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, 0, len);
+ }
+ else {
+ m_attributes = null;
+ }
+
+ m_x = NumberUtils.TheNaN;
+ m_y = NumberUtils.TheNaN;
}
@Override
@@ -423,7 +426,7 @@ public void applyTransformation(Transformation2D transform) {
}
@Override
- void applyTransformation(Transformation3D transform) {
+ public void applyTransformation(Transformation3D transform) {
if (isEmptyImpl())
return;
@@ -436,20 +439,27 @@ void applyTransformation(Transformation3D transform) {
public void copyTo(Geometry dst) {
if (dst.getType() != Type.Point)
throw new IllegalArgumentException();
-
- Point pointDst = (Point) dst;
+
+ if (this == dst)
+ return;
+
dst._touch();
- if (m_attributes == null) {
- pointDst.setEmpty();
+ Point pointDst = (Point) dst;
+ dst.m_description = m_description;
+ pointDst.m_x = m_x;
+ pointDst.m_y = m_y;
+ int attrLen = m_description.getTotalComponentCount() - 2;
+ if (attrLen == 0) {
pointDst.m_attributes = null;
- pointDst.assignVertexDescription(m_description);
- } else {
- pointDst.assignVertexDescription(m_description);
- pointDst.resizeAttributes(m_description._getTotalComponents());
- attributeCopy(m_attributes, pointDst.m_attributes,
- m_description._getTotalComponents());
+ return;
+ }
+
+ if (pointDst.m_attributes == null || pointDst.m_attributes.length != attrLen) {
+ pointDst.m_attributes = new double[attrLen];
}
+
+ System.arraycopy(m_attributes, 0, pointDst.m_attributes, 0, attrLen);
}
@Override
@@ -464,30 +474,29 @@ public boolean isEmpty() {
}
final boolean isEmptyImpl() {
- return ((m_attributes == null) || NumberUtils.isNaN(m_attributes[0]) || NumberUtils
- .isNaN(m_attributes[1]));
+ return NumberUtils.isNaN(m_x) || NumberUtils.isNaN(m_y);
}
@Override
public void queryEnvelope(Envelope env) {
- env.setEmpty();
if (m_description != env.m_description)
env.assignVertexDescription(m_description);
+
+ env.setEmpty();
env.merge(this);
}
@Override
public void queryEnvelope2D(Envelope2D env) {
-
if (isEmptyImpl()) {
env.setEmpty();
return;
}
- env.xmin = m_attributes[0];
- env.ymin = m_attributes[1];
- env.xmax = m_attributes[0];
- env.ymax = m_attributes[1];
+ env.xmin = m_x;
+ env.ymin = m_y;
+ env.xmax = m_x;
+ env.ymax = m_y;
}
@Override
@@ -497,13 +506,13 @@ void queryEnvelope3D(Envelope3D env) {
return;
}
- Point3D pt = getXYZ();
- env.xmin = pt.x;
- env.ymin = pt.y;
- env.zmin = pt.z;
- env.xmax = pt.x;
- env.ymax = pt.y;
- env.zmax = pt.z;
+ env.xmin = m_x;
+ env.ymin = m_y;
+ env.xmax = m_x;
+ env.ymax = m_y;
+ double z = getZ();
+ env.zmin = z;
+ env.zmax = z;
}
@Override
@@ -520,21 +529,6 @@ public Envelope1D queryInterval(int semantics, int ordinate) {
return env;
}
- private void resizeAttributes(int newSize) {
- if (m_attributes == null) {
- m_attributes = new double[newSize];
- } else if (m_attributes.length < newSize) {
- double[] newbuffer = new double[newSize];
- System.arraycopy(m_attributes, 0, newbuffer, 0, m_attributes.length);
- m_attributes = newbuffer;
- }
- }
-
- static void attributeCopy(double[] src, double[] dst, int count) {
- for (int i = 0; i < count; i++)
- dst[i] = src[i];
- }
-
/**
* Set the X and Y coordinate of the point.
*
@@ -546,11 +540,8 @@ static void attributeCopy(double[] src, double[] dst, int count) {
public void setXY(double x, double y) {
_touch();
- if (m_attributes == null)
- _setToDefault();
-
- m_attributes[0] = x;
- m_attributes[1] = y;
+ m_x = x;
+ m_y = y;
}
/**
@@ -570,15 +561,21 @@ public boolean equals(Object _other) {
if (m_description != otherPt.m_description)
return false;
- if (isEmptyImpl())
+ if (isEmptyImpl()) {
if (otherPt.isEmptyImpl())
return true;
else
return false;
+ }
+
+ if (m_x != otherPt.m_x || m_y != otherPt.m_y) {
+ return false;
+ }
- for (int i = 0, n = m_description._getTotalComponents(); i < n; i++)
- if (m_attributes[i] != otherPt.m_attributes[i])
+ for (int i = 0, n = m_description.getTotalComponentCount() - 2; i < n; i++) {
+ if (!NumberUtils.isEqualNonIEEE(m_attributes[i], otherPt.m_attributes[i]))
return false;
+ }
return true;
}
@@ -591,12 +588,34 @@ public boolean equals(Object _other) {
public int hashCode() {
int hashCode = m_description.hashCode();
if (!isEmptyImpl()) {
- for (int i = 0, n = m_description._getTotalComponents(); i < n; i++) {
+ hashCode = NumberUtils.hash(hashCode, m_x);
+ hashCode = NumberUtils.hash(hashCode, m_y);
+ for (int i = 0, n = m_description.getTotalComponentCount() - 2; i < n; i++) {
long bits = Double.doubleToLongBits(m_attributes[i]);
int hc = (int) (bits ^ (bits >>> 32));
hashCode = NumberUtils.hash(hashCode, hc);
}
}
+
return hashCode;
}
+
+ @Override
+ public Geometry getBoundary() {
+ return null;
+ }
+
+ @Override
+ public void replaceNaNs(int semantics, double value) {
+ addAttribute(semantics);
+ if (isEmpty())
+ return;
+
+ int ncomps = VertexDescription.getComponentCount(semantics);
+ for (int i = 0; i < ncomps; i++) {
+ double v = getAttributeAsDbl(semantics, i);
+ if (Double.isNaN(v))
+ setAttribute(semantics, i, value);
+ }
+ }
}
diff --git a/src/main/java/com/esri/core/geometry/Point2D.java b/src/main/java/com/esri/core/geometry/Point2D.java
new file mode 100644
index 00000000..95a46c66
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/Point2D.java
@@ -0,0 +1,764 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+
+package com.esri.core.geometry;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Comparator;
+
+/**
+ *
+ * Basic 2D point class. Contains only two double fields.
+ *
+ */
+public final class Point2D implements Serializable{
+ private static final long serialVersionUID = 1L;
+
+ public double x;
+ public double y;
+
+ public Point2D() {
+ }
+
+ public Point2D(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public Point2D(Point2D other) {
+ setCoords(other);
+ }
+
+ public static Point2D construct(double x, double y) {
+ return new Point2D(x, y);
+ }
+
+ public void setCoords(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public void setCoords(Point2D other) {
+ x = other.x;
+ y = other.y;
+ }
+
+ public boolean isEqual(Point2D other) {
+ return x == other.x && y == other.y;
+ }
+
+ public boolean isEqual(double x_, double y_) {
+ return x == x_ && y == y_;
+ }
+
+ public boolean isEqual(Point2D other, double tol) {
+ return (Math.abs(x - other.x) <= tol) && (Math.abs(y - other.y) <= tol);
+ }
+
+ public boolean equals(Point2D other) {
+ return x == other.x && y == other.y;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this)
+ return true;
+
+ if (!(other instanceof Point2D))
+ return false;
+
+ Point2D v = (Point2D)other;
+
+ return x == v.x && y == v.y;
+ }
+
+ @Override
+ public int hashCode() {
+ return NumberUtils.hash(NumberUtils.hash(x), y);
+ }
+
+
+ public void sub(Point2D other) {
+ x -= other.x;
+ y -= other.y;
+ }
+
+ public void sub(Point2D p1, Point2D p2) {
+ x = p1.x - p2.x;
+ y = p1.y - p2.y;
+ }
+
+ public void add(Point2D other) {
+ x += other.x;
+ y += other.y;
+ }
+
+ public void add(Point2D p1, Point2D p2) {
+ x = p1.x + p2.x;
+ y = p1.y + p2.y;
+ }
+
+ public void negate() {
+ x = -x;
+ y = -y;
+ }
+
+ public void negate(Point2D other) {
+ x = -other.x;
+ y = -other.y;
+ }
+
+ public void interpolate(Point2D other, double alpha) {
+ MathUtils.lerp(this, other, alpha, this);
+ }
+
+ public void interpolate(Point2D p1, Point2D p2, double alpha) {
+ MathUtils.lerp(p1, p2, alpha, this);
+ }
+
+ /**
+ * Calculates this = this * f + shift
+ * @param f
+ * @param shift
+ */
+ public void scaleAdd(double f, Point2D shift) {
+ x = x * f + shift.x;
+ y = y * f + shift.y;
+ }
+
+ /**
+ * Calculates this = other * f + shift
+ * @param f
+ * @param other
+ * @param shift
+ */
+ public void scaleAdd(double f, Point2D other, Point2D shift) {
+ x = other.x * f + shift.x;
+ y = other.y * f + shift.y;
+ }
+
+ public void scale(double f, Point2D other) {
+ x = f * other.x;
+ y = f * other.y;
+ }
+
+ public void scale(double f) {
+ x *= f;
+ y *= f;
+ }
+
+ /**
+ * Compares two vertices lexicographically by y.
+ */
+ public int compare(Point2D other) {
+ return y < other.y ? -1 : (y > other.y ? 1 : (x < other.x ? -1
+ : (x > other.x ? 1 : 0)));
+ }
+ /**
+ * Compares two vertices lexicographically by x.
+ */
+ int compareX(Point2D other) {
+ return x < other.x ? -1 : (x > other.x ? 1 : (y < other.y ? -1
+ : (y > other.y ? 1 : 0)));
+ }
+
+ public void normalize(Point2D other) {
+ double len = other.length();
+ if (len == 0) {
+ x = 1.0;
+ y = 0.0;
+ } else {
+ x = other.x / len;
+ y = other.y / len;
+ }
+ }
+
+ public void normalize() {
+ double len = length();
+ if (len == 0)// (!len)
+ {
+ x = 1.0;
+ y = 0.0;
+ }
+ x /= len;
+ y /= len;
+ }
+
+ public double length() {
+ return Math.sqrt(x * x + y * y);
+ }
+
+ public double sqrLength() {
+ return x * x + y * y;
+ }
+
+ public static double distance(Point2D pt1, Point2D pt2) {
+ return Math.sqrt(sqrDistance(pt1, pt2));
+ }
+
+ public double dotProduct(Point2D other) {
+ return x * other.x + y * other.y;
+ }
+
+ double _dotProductAbs(Point2D other) {
+ return Math.abs(x * other.x) + Math.abs(y * other.y);
+ }
+
+ public double crossProduct(Point2D other) {
+ return x * other.y - y * other.x;
+ }
+
+ public void rotateDirect(double Cos, double Sin) // corresponds to the
+ // Transformation2D.SetRotate(cos,
+ // sin).Transform(pt)
+ {
+ double xx = x * Cos - y * Sin;
+ double yy = x * Sin + y * Cos;
+ x = xx;
+ y = yy;
+ }
+
+ public void rotateReverse(double Cos, double Sin) {
+ double xx = x * Cos + y * Sin;
+ double yy = -x * Sin + y * Cos;
+ x = xx;
+ y = yy;
+ }
+
+ /**
+ * 90 degree rotation, anticlockwise. Equivalent to RotateDirect(cos(pi/2),
+ * sin(pi/2)).
+ */
+ public void leftPerpendicular() {
+ double xx = x;
+ x = -y;
+ y = xx;
+ }
+
+ /**
+ * 90 degree rotation, anticlockwise. Equivalent to RotateDirect(cos(pi/2),
+ * sin(pi/2)).
+ */
+ public void leftPerpendicular(Point2D pt) {
+ x = -pt.y;
+ y = pt.x;
+ }
+
+ /**
+ * 270 degree rotation, anticlockwise. Equivalent to
+ * RotateDirect(-cos(pi/2), sin(-pi/2)).
+ */
+ public void rightPerpendicular() {
+ double xx = x;
+ x = y;
+ y = -xx;
+ }
+
+ /**
+ * 270 degree rotation, anticlockwise. Equivalent to
+ * RotateDirect(-cos(pi/2), sin(-pi/2)).
+ */
+ public void rightPerpendicular(Point2D pt) {
+ x = pt.y;
+ y = -pt.x;
+ }
+
+ void _setNan() {
+ x = NumberUtils.NaN();
+ y = NumberUtils.NaN();
+ }
+
+ boolean _isNan() {
+ return NumberUtils.isNaN(x) || NumberUtils.isNaN(y);
+ }
+
+ // calculates which quarter of xy plane the vector lies in. First quater is
+ // between vectors (1,0) and (0, 1), second between (0, 1) and (-1, 0), etc.
+ // Angle intervals corresponding to quarters: 1 : [0 : 90); 2 : [90 : 180);
+ // 3 : [180 : 270); 4 : [270 : 360)
+ final int _getQuarter() {
+ if (x > 0) {
+ if (y >= 0)
+ return 1; // x > 0 && y <= 0
+ else
+ return 4; // y < 0 && x > 0. Should be x >= 0 && y < 0. The x ==
+ // 0 case is processed later.
+ } else {
+ if (y > 0)
+ return 2; // x <= 0 && y > 0
+ else
+ return x == 0 ? 4 : 3; // 3: x < 0 && y <= 0. The case x == 0 &&
+ // y <= 0 is attribute to the case 4.
+ // The point x==0 and y==0 is a bug, but
+ // will be assigned to 4.
+ }
+ }
+
+ /**
+ * Calculates which quarter of XY plane the vector lies in. First quarter is
+ * between vectors (1,0) and (0, 1), second between (0, 1) and (-1, 0), etc.
+ * The quarters are numbered counterclockwise.
+ * Angle intervals corresponding to quarters: 1 : [0 : 90); 2 : [90 : 180);
+ * 3 : [180 : 270); 4 : [270 : 360)
+ */
+ public int getQuarter() { return _getQuarter(); }
+
+ // Assume vector v1 and v2 have same origin. The function compares the
+ // vectors by angle from the x axis to the vector in the counter clockwise
+ // direction.
+ // > >
+ // \ /
+ // V3 \ / V1
+ // \
+ // \
+ // >V2
+ // _compareVectors(V1, V2) == -1.
+ // _compareVectors(V1, V3) == -1
+ // _compareVectors(V2, V3) == 1
+ //
+ final static int _compareVectors(Point2D v1, Point2D v2) {
+ int q1 = v1._getQuarter();
+ int q2 = v2._getQuarter();
+
+ if (q2 == q1) {
+ double cross = v1.crossProduct(v2);
+ return cross < 0 ? 1 : (cross > 0 ? -1 : 0);
+ } else
+ return q1 < q2 ? -1 : 1;
+ }
+
+ /**
+ * Assume vector v1 and v2 have same origin. The function compares the
+ * vectors by angle in the counter clockwise direction from the axis X.
+ *
+ * For example, V1 makes 30 degree angle counterclockwise from horizontal x axis
+ * V2, makes 270, V3 makes 90, then
+ * compareVectors(V1, V2) == -1.
+ * compareVectors(V1, V3) == -1.
+ * compareVectors(V2, V3) == 1.
+ * @return Returns 1 if v1 is less than v2, 0 if equal, and 1 if greater.
+ */
+ public static int compareVectors(Point2D v1, Point2D v2) {
+ return _compareVectors(v1, v2);
+ }
+
+ static class CompareVectors implements Comparator {
+ @Override
+ public int compare(Point2D v1, Point2D v2) {
+ return _compareVectors((Point2D) v1, (Point2D) v2);
+ }
+ }
+
+ public static double sqrDistance(Point2D pt1, Point2D pt2) {
+ double dx = pt1.x - pt2.x;
+ double dy = pt1.y - pt2.y;
+ return dx * dx + dy * dy;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + x + " , " + y + ")";
+ }
+
+ public void setNaN() {
+ x = NumberUtils.NaN();
+ y = NumberUtils.NaN();
+ }
+
+ public boolean isNaN() {
+ return NumberUtils.isNaN(x) || NumberUtils.isNaN(y);
+ }
+
+ // metric = 1: Manhattan metric
+ // 2: Euclidian metric (default)
+ // 0: used for L-infinite (max(fabs(x), fabs(y))
+ // for predefined metrics, use the DistanceMetricEnum defined in WKSPoint.h
+ double _norm(int metric) {
+ if (metric < 0 || _isNan())
+ return NumberUtils.NaN();
+
+ switch (metric) {
+ case 0: // L-infinite
+ return Math.abs(x) >= Math.abs(y) ? Math.abs(x) : Math.abs(y);
+
+ case 1: // L1 or Manhattan metric
+ return Math.abs(x) + Math.abs(y);
+
+ case 2: // L2 or Euclidean metric
+ return Math.sqrt(x * x + y * y);
+
+ default:
+ return Math
+ .pow(Math.pow(x, (double) metric)
+ + Math.pow(y, (double) metric),
+ 1.0 / (double) metric);
+ }
+ }
+
+ /**
+ * returns signed distance of point from infinite line represented by
+ * pt_1...pt_2. The returned distance is positive if this point lies on the
+ * right-hand side of the line, negative otherwise. If the two input points
+ * are equal, the (positive) distance of this point to p_1 is returned.
+ */
+ double offset(/* const */Point2D pt1, /* const */Point2D pt2) {
+ double newDistance = distance(pt1, pt2);
+ Point2D p = construct(x, y);
+ if (newDistance == 0.0)
+ return distance(p, pt1);
+
+ // get vectors relative to pt_1
+ Point2D p2 = new Point2D();
+ p2.setCoords(pt2);
+ p2.sub(pt1);
+ p.sub(pt1);
+
+ double cross = p.crossProduct(p2);
+ return cross / newDistance;
+ }
+
+ /**
+ * Calculates the orientation of the triangle formed by p, q, r. Returns 1
+ * for counter-clockwise, -1 for clockwise, and 0 for collinear. May use
+ * high precision arithmetics for some special degenerate cases.
+ */
+ public static int orientationRobust(Point2D p, Point2D q, Point2D r) {
+ ECoordinate det_ec = new ECoordinate();
+ det_ec.set(q.x);
+ det_ec.sub(p.x);
+
+ ECoordinate rp_y_ec = new ECoordinate();
+ rp_y_ec.set(r.y);
+ rp_y_ec.sub(p.y);
+
+ ECoordinate qp_y_ec = new ECoordinate();
+ qp_y_ec.set(q.y);
+ qp_y_ec.sub(p.y);
+
+ ECoordinate rp_x_ec = new ECoordinate();
+ rp_x_ec.set(r.x);
+ rp_x_ec.sub(p.x);
+
+ det_ec.mul(rp_y_ec);
+ qp_y_ec.mul(rp_x_ec);
+ det_ec.sub(qp_y_ec);
+
+ if (!det_ec.isFuzzyZero()) {
+ double det_ec_value = det_ec.value();
+
+ if (det_ec_value < 0.0)
+ return -1;
+
+ if (det_ec_value > 0.0)
+ return 1;
+
+ return 0;
+ }
+
+ // Need extended precision
+
+ BigDecimal det_mp = new BigDecimal(q.x);
+ BigDecimal px_mp = new BigDecimal(p.x);
+ BigDecimal py_mp = new BigDecimal(p.y);
+ det_mp = det_mp.subtract(px_mp);
+
+ BigDecimal rp_y_mp = new BigDecimal(r.y);
+ rp_y_mp = rp_y_mp.subtract(py_mp);
+
+ BigDecimal qp_y_mp = new BigDecimal(q.y);
+ qp_y_mp = qp_y_mp.subtract(py_mp);
+
+ BigDecimal rp_x_mp = new BigDecimal(r.x);
+ rp_x_mp = rp_x_mp.subtract(px_mp);
+
+ det_mp = det_mp.multiply(rp_y_mp);
+ qp_y_mp = qp_y_mp.multiply(rp_x_mp);
+ det_mp = det_mp.subtract(qp_y_mp);
+
+ return det_mp.signum();
+ }
+
+ private static int inCircleRobustMP_(Point2D p, Point2D q, Point2D r, Point2D s) {
+ BigDecimal sx_mp = new BigDecimal(s.x), sy_mp = new BigDecimal(s.y);
+
+ BigDecimal psx_mp = new BigDecimal(p.x), psy_mp = new BigDecimal(p.y);
+ psx_mp = psx_mp.subtract(sx_mp);
+ psy_mp = psy_mp.subtract(sy_mp);
+
+ BigDecimal qsx_mp = new BigDecimal(q.x), qsy_mp = new BigDecimal(q.y);
+ qsx_mp = qsx_mp.subtract(sx_mp);
+ qsy_mp = qsy_mp.subtract(sy_mp);
+
+ BigDecimal rsx_mp = new BigDecimal(r.x), rsy_mp = new BigDecimal(r.y);
+ rsx_mp = rsx_mp.subtract(sx_mp);
+ rsy_mp = rsy_mp.subtract(sy_mp);
+
+ BigDecimal pq_det_mp = psx_mp.multiply(qsy_mp).subtract(psy_mp.multiply(qsx_mp));
+ BigDecimal qr_det_mp = qsx_mp.multiply(rsy_mp).subtract(qsy_mp.multiply(rsx_mp));
+ BigDecimal pr_det_mp = psx_mp.multiply(rsy_mp).subtract(psy_mp.multiply(rsx_mp));
+
+ BigDecimal p_parab_mp = psx_mp.multiply(psx_mp).add(psy_mp.multiply(psy_mp));
+ BigDecimal q_parab_mp = qsx_mp.multiply(qsx_mp).add(qsy_mp.multiply(qsy_mp));
+ BigDecimal r_parab_mp = rsx_mp.multiply(rsx_mp).add(rsy_mp.multiply(rsy_mp));
+
+ BigDecimal det_mp = (p_parab_mp.multiply(qr_det_mp).subtract(q_parab_mp.multiply(pr_det_mp)))
+ .add(r_parab_mp.multiply(pq_det_mp));
+
+ return det_mp.signum();
+ }
+
+ /**
+ * Calculates if the point s is inside of the circumcircle inscribed by the clockwise oriented triangle p-q-r.
+ * Returns 1 for outside, -1 for inside, and 0 for cocircular.
+ * Note that the convention used here differs from what is commonly found in literature, which can define the relation
+ * in terms of a counter-clockwise oriented circle, and this flips the sign (think of the signed volume of the tetrahedron).
+ * May use high precision arithmetics for some special cases.
+ */
+ static int inCircleRobust(Point2D p, Point2D q, Point2D r, Point2D s) {
+ ECoordinate psx_ec = new ECoordinate(), psy_ec = new ECoordinate();
+ psx_ec.set(p.x);
+ psx_ec.sub(s.x);
+ psy_ec.set(p.y);
+ psy_ec.sub(s.y);
+
+ ECoordinate qsx_ec = new ECoordinate(), qsy_ec = new ECoordinate();
+ qsx_ec.set(q.x);
+ qsx_ec.sub(s.x);
+ qsy_ec.set(q.y);
+ qsy_ec.sub(s.y);
+
+ ECoordinate rsx_ec = new ECoordinate(), rsy_ec = new ECoordinate();
+ rsx_ec.set(r.x);
+ rsx_ec.sub(s.x);
+ rsy_ec.set(r.y);
+ rsy_ec.sub(s.y);
+
+ ECoordinate psx_ec_qsy_ec = new ECoordinate();
+ psx_ec_qsy_ec.set(psx_ec);
+ psx_ec_qsy_ec.mul(qsy_ec);
+ ECoordinate psy_ec_qsx_ec = new ECoordinate();
+ psy_ec_qsx_ec.set(psy_ec);
+ psy_ec_qsx_ec.mul(qsx_ec);
+ ECoordinate qsx_ec_rsy_ec = new ECoordinate();
+ qsx_ec_rsy_ec.set(qsx_ec);
+ qsx_ec_rsy_ec.mul(rsy_ec);
+ ECoordinate qsy_ec_rsx_ec = new ECoordinate();
+ qsy_ec_rsx_ec.set(qsy_ec);
+ qsy_ec_rsx_ec.mul(rsx_ec);
+ ECoordinate psx_ec_rsy_ec = new ECoordinate();
+ psx_ec_rsy_ec.set(psx_ec);
+ psx_ec_rsy_ec.mul(rsy_ec);
+ ECoordinate psy_ec_rsx_ec = new ECoordinate();
+ psy_ec_rsx_ec.set(psy_ec);
+ psy_ec_rsx_ec.mul(rsx_ec);
+
+ ECoordinate pq_det_ec = new ECoordinate();
+ pq_det_ec.set(psx_ec_qsy_ec);
+ pq_det_ec.sub(psy_ec_qsx_ec);
+ ECoordinate qr_det_ec = new ECoordinate();
+ qr_det_ec.set(qsx_ec_rsy_ec);
+ qr_det_ec.sub(qsy_ec_rsx_ec);
+ ECoordinate pr_det_ec = new ECoordinate();
+ pr_det_ec.set(psx_ec_rsy_ec);
+ pr_det_ec.sub(psy_ec_rsx_ec);
+
+ ECoordinate psx_ec_psx_ec = new ECoordinate();
+ psx_ec_psx_ec.set(psx_ec);
+ psx_ec_psx_ec.mul(psx_ec);
+ ECoordinate psy_ec_psy_ec = new ECoordinate();
+ psy_ec_psy_ec.set(psy_ec);
+ psy_ec_psy_ec.mul(psy_ec);
+ ECoordinate qsx_ec_qsx_ec = new ECoordinate();
+ qsx_ec_qsx_ec.set(qsx_ec);
+ qsx_ec_qsx_ec.mul(qsx_ec);
+ ECoordinate qsy_ec_qsy_ec = new ECoordinate();
+ qsy_ec_qsy_ec.set(qsy_ec);
+ qsy_ec_qsy_ec.mul(qsy_ec);
+ ECoordinate rsx_ec_rsx_ec = new ECoordinate();
+ rsx_ec_rsx_ec.set(rsx_ec);
+ rsx_ec_rsx_ec.mul(rsx_ec);
+ ECoordinate rsy_ec_rsy_ec = new ECoordinate();
+ rsy_ec_rsy_ec.set(rsy_ec);
+ rsy_ec_rsy_ec.mul(rsy_ec);
+
+ ECoordinate p_parab_ec = new ECoordinate();
+ p_parab_ec.set(psx_ec_psx_ec);
+ p_parab_ec.add(psy_ec_psy_ec);
+ ECoordinate q_parab_ec = new ECoordinate();
+ q_parab_ec.set(qsx_ec_qsx_ec);
+ q_parab_ec.add(qsy_ec_qsy_ec);
+ ECoordinate r_parab_ec = new ECoordinate();
+ r_parab_ec.set(rsx_ec_rsx_ec);
+ r_parab_ec.add(rsy_ec_rsy_ec);
+
+ p_parab_ec.mul(qr_det_ec);
+ q_parab_ec.mul(pr_det_ec);
+ r_parab_ec.mul(pq_det_ec);
+
+ ECoordinate det_ec = new ECoordinate();
+ det_ec.set(p_parab_ec);
+ det_ec.sub(q_parab_ec);
+ det_ec.add(r_parab_ec);
+
+ if (!det_ec.isFuzzyZero()) {
+ double det_ec_value = det_ec.value();
+
+ if (det_ec_value < 0.0)
+ return -1;
+
+ if (det_ec_value > 0.0)
+ return 1;
+
+ return 0;
+ }
+
+ return inCircleRobustMP_(p, q, r, s);
+ }
+
+ private static Point2D calculateCenterFromThreePointsHelperMP_(Point2D from, Point2D mid_point, Point2D to) {
+ assert(!mid_point.isEqual(to) && !mid_point.isEqual(from) && !from.isEqual(to));
+ BigDecimal mx = new BigDecimal(mid_point.x);
+ mx = mx.subtract(new BigDecimal(from.x));
+ BigDecimal my = new BigDecimal(mid_point.y);
+ my = my.subtract(new BigDecimal(from.y));
+ BigDecimal tx = new BigDecimal(to.x);
+ tx = tx.subtract(new BigDecimal(from.x));
+ BigDecimal ty = new BigDecimal(to.y);
+ ty = ty.subtract(new BigDecimal(from.y));
+
+ BigDecimal d = mx.multiply(ty);
+ BigDecimal tmp = my.multiply(tx);
+ d = d.subtract(tmp);
+
+ if (d.signum() == 0) {
+ return Point2D.construct(NumberUtils.NaN(), NumberUtils.NaN());
+ }
+
+ d = d.multiply(new BigDecimal(2.0));
+
+ BigDecimal mx2 = mx.multiply(mx);
+ BigDecimal my2 = my.multiply(my);
+ BigDecimal m_norm2 = mx2.add(my2);
+ BigDecimal tx2 = tx.multiply(tx);
+ BigDecimal ty2 = ty.multiply(ty);
+ BigDecimal t_norm2 = tx2.add(ty2);
+
+ BigDecimal xo = my.multiply(t_norm2);
+ tmp = ty.multiply(m_norm2);
+ xo = xo.subtract(tmp);
+ xo = xo.divide(d, BigDecimal.ROUND_HALF_EVEN);
+
+ BigDecimal yo = mx.multiply(t_norm2);
+ tmp = tx.multiply(m_norm2);
+ yo = yo.subtract(tmp);
+ yo = yo.divide(d, BigDecimal.ROUND_HALF_EVEN);
+
+ Point2D center = Point2D.construct(from.x - xo.doubleValue(), from.y + yo.doubleValue());
+ return center;
+ }
+
+ private static Point2D calculateCenterFromThreePointsHelper_(Point2D from, Point2D mid_point, Point2D to) {
+ assert(!mid_point.isEqual(to) && !mid_point.isEqual(from) && !from.isEqual(to));
+ ECoordinate mx = new ECoordinate(mid_point.x);
+ mx.sub(from.x);
+ ECoordinate my = new ECoordinate(mid_point.y);
+ my.sub(from.y);
+ ECoordinate tx = new ECoordinate(to.x);
+ tx.sub(from.x);
+ ECoordinate ty = new ECoordinate(to.y);
+ ty.sub(from.y);
+
+ ECoordinate d = new ECoordinate(mx);
+ d.mul(ty);
+ ECoordinate tmp = new ECoordinate(my);
+ tmp.mul(tx);
+ d.sub(tmp);
+
+ if (d.value() == 0.0) {
+ return Point2D.construct(NumberUtils.NaN(), NumberUtils.NaN());
+ }
+
+ d.mul(2.0);
+
+ ECoordinate mx2 = new ECoordinate(mx);
+ mx2.mul(mx);
+ ECoordinate my2 = new ECoordinate(my);
+ my2.mul(my);
+ ECoordinate m_norm2 = new ECoordinate(mx2);
+ m_norm2.add(my2);
+ ECoordinate tx2 = new ECoordinate(tx);
+ tx2.mul(tx);
+ ECoordinate ty2 = new ECoordinate(ty);
+ ty2.mul(ty);
+ ECoordinate t_norm2 = new ECoordinate(tx2);
+ t_norm2.add(ty2);
+
+ ECoordinate xo = new ECoordinate(my);
+ xo.mul(t_norm2);
+ tmp = new ECoordinate(ty);
+ tmp.mul(m_norm2);
+ xo.sub(tmp);
+ xo.div(d);
+
+ ECoordinate yo = new ECoordinate(mx);
+ yo.mul(t_norm2);
+ tmp = new ECoordinate(tx);
+ tmp.mul(m_norm2);
+ yo.sub(tmp);
+ yo.div(d);
+
+ Point2D center = Point2D.construct(from.x - xo.value(), from.y + yo.value());
+ double r1 = Point2D.construct(from.x - center.x, from.y - center.y).length();
+ double r2 = Point2D.construct(mid_point.x - center.x, mid_point.y - center.y).length();
+ double r3 = Point2D.construct(to.x - center.x, to.y - center.y).length();
+ double base = r1 + Math.abs(from.x) + Math.abs(mid_point.x) + Math.abs(to.x) + Math.abs(from.y)
+ + Math.abs(mid_point.y) + Math.abs(to.y);
+
+ double tol = 1e-15;
+ if ((Math.abs(r1 - r2) <= base * tol && Math.abs(r1 - r3) <= base * tol))
+ return center;//returns center value for MP_value type or when calculated radius value for from - center, mid - center, and to - center are very close.
+
+ return Point2D.construct(NumberUtils.NaN(), NumberUtils.NaN());
+ }
+
+ static Point2D calculateCircleCenterFromThreePoints(Point2D from, Point2D mid_point, Point2D to) {
+ if (from.isEqual(to) || from.isEqual(mid_point) || to.isEqual(mid_point)) {
+ return new Point2D(NumberUtils.NaN(), NumberUtils.NaN());
+ }
+
+ Point2D pt = calculateCenterFromThreePointsHelper_(from, mid_point, to); //use error tracking calculations
+ if (pt.isNaN())
+ return calculateCenterFromThreePointsHelperMP_(from, mid_point, to); //use precise calculations
+ else {
+ return pt;
+ }
+ }
+
+ double getAxis(int ordinate) {
+ assert(ordinate == 0 || ordinate == 1);
+ return (ordinate == 0 ? x : y);
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/Point3D.java b/src/main/java/com/esri/core/geometry/Point3D.java
new file mode 100644
index 00000000..71cbfdba
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/Point3D.java
@@ -0,0 +1,162 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+
+package com.esri.core.geometry;
+
+import java.io.Serializable;
+
+/**
+ *
+ * Basic 3D point class.
+ *
+ */
+public final class Point3D implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public double x;
+ public double y;
+ public double z;
+
+ public Point3D() {
+ }
+
+ public Point3D(Point3D other) {
+ setCoords(other);
+ }
+
+ public Point3D(double x, double y, double z) {
+ setCoords(x, y, z);
+ }
+
+ public static Point3D construct(double x, double y, double z) {
+ Point3D pt = new Point3D();
+ pt.setCoords(x, y, z);
+ return pt;
+ }
+
+ public void setCoords(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public void setCoords(Point3D other) {
+ setCoords(other.x, other.y, other.z);
+ }
+
+ public void setZero() {
+ x = 0.0;
+ y = 0.0;
+ z = 0.0;
+ }
+
+ public void normalize() {
+ double len = length();
+ if (len == 0) {
+ x = 1.0;
+ y = 0.0;
+ z = 0.0;
+ } else {
+ x /= len;
+ y /= len;
+ z /= len;
+ }
+ }
+
+ public double dotProduct(Point3D other) {
+ return x * other.x + y * other.y + z * other.z;
+ }
+
+ public double sqrLength() {
+ return x * x + y * y + z * z;
+ }
+
+ public double length() {
+ return Math.sqrt(x * x + y * y + z * z);
+ }
+
+ public void sub(Point3D other)
+ {
+ x -= other.x;
+ y -= other.y;
+ z -= other.z;
+ }
+
+ public void sub(Point3D p1, Point3D p2) {
+ x = p1.x - p2.x;
+ y = p1.y - p2.y;
+ z = p1.z - p2.z;
+ }
+
+ public void scale(double f, Point3D other) {
+ x = f * other.x;
+ y = f * other.y;
+ z = f * other.z;
+ }
+
+ public void mul(double factor) {
+ x *= factor;
+ y *= factor;
+ z *= factor;
+ }
+
+ void _setNan() {
+ x = NumberUtils.NaN();
+ y = NumberUtils.NaN();
+ z = NumberUtils.NaN();
+ }
+
+ boolean _isNan() {
+ return NumberUtils.isNaN(x) || NumberUtils.isNaN(y) || NumberUtils.isNaN(z);
+ }
+
+ public boolean equals(Point3D other) {
+ //note that for nan value this returns false.
+ //this is by design for this class.
+ return x == other.x && y == other.y && z == other.z;
+ }
+
+ @Override
+ public boolean equals(Object other_) {
+ if (other_ == this)
+ return true;
+
+ if (!(other_ instanceof Point3D))
+ return false;
+
+ Point3D other = (Point3D)other_;
+ //note that for nan value this returns false.
+ //this is by design for this class.
+ return x == other.x && y == other.y && z == other.z;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = NumberUtils.hash(x);
+ hash = NumberUtils.hash(hash, y);
+ hash = NumberUtils.hash(hash, z);
+ return hash;
+ }
+}
diff --git a/src/com/esri/core/geometry/PointInPolygonHelper.java b/src/main/java/com/esri/core/geometry/PointInPolygonHelper.java
similarity index 75%
rename from src/com/esri/core/geometry/PointInPolygonHelper.java
rename to src/main/java/com/esri/core/geometry/PointInPolygonHelper.java
index 1d4e6986..801b2b81 100644
--- a/src/com/esri/core/geometry/PointInPolygonHelper.java
+++ b/src/main/java/com/esri/core/geometry/PointInPolygonHelper.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
package com.esri.core.geometry;
-class PointInPolygonHelper {
+final class PointInPolygonHelper {
private Point2D m_inputPoint;
private int m_windnum;
@@ -164,7 +164,7 @@ private boolean processSegment(Segment segment) {
private static int _isPointInPolygonInternal(Polygon inputPolygon,
Point2D inputPoint, double tolerance) {
- boolean bAltenate = true;// Path.get_FillMode() == fillmodeAlternate;
+ boolean bAltenate = inputPolygon.getFillRule() == Polygon.FillRule.enumFillRuleOddEven;
PointInPolygonHelper helper = new PointInPolygonHelper(bAltenate,
inputPoint, tolerance);
MultiPathImpl mpImpl = (MultiPathImpl) inputPolygon._getImpl();
@@ -187,7 +187,7 @@ private static int _isPointInPolygonInternalWithQuadTree(
inputPolygon.queryLooseEnvelope(envPoly);
envPoly.inflate(tolerance, tolerance);
- boolean bAltenate = true;// Path.get_FillMode() == fillmodeAlternate;
+ boolean bAltenate = inputPolygon.getFillRule() == Polygon.FillRule.enumFillRuleOddEven;
PointInPolygonHelper helper = new PointInPolygonHelper(bAltenate,
inputPoint, tolerance);
@@ -229,7 +229,7 @@ public static int isPointInPolygon(Polygon inputPolygon,
MultiPathImpl mpImpl = (MultiPathImpl) inputPolygon._getImpl();
GeometryAccelerators accel = mpImpl._getAccelerators();
if (accel != null) {
- //geometry has spatial indices built. Try using them.
+ // geometry has spatial indices built. Try using them.
RasterizedGeometry2D rgeom = accel.getRasterizedGeometry();
if (rgeom != null) {
RasterizedGeometry2D.HitType hit = rgeom.queryPointInGeometry(
@@ -241,7 +241,7 @@ else if (hit == RasterizedGeometry2D.HitType.Outside)
}
QuadTreeImpl qtree = accel.getQuadTree();
- if (qtree != null) {
+ if (qtree != null) {
return _isPointInPolygonInternalWithQuadTree(inputPolygon,
qtree, inputPoint, tolerance);
}
@@ -275,35 +275,66 @@ else if (hit == RasterizedGeometry2D.HitType.Outside)
}
}
- // FIXME, the rest of the point in polygon tests are set up to avoid
- // Point2D. This is the last bit
return _isPointInPolygonInternal(inputPolygon, new Point2D(
inputPointXVal, inputPointYVal), tolerance);
}
public static int isPointInRing(MultiPathImpl inputPolygonImpl, int iRing,
- Point2D inputPoint, double tolerance) {
+ Point2D inputPoint, double tolerance, QuadTree quadTree) {
Envelope2D env = new Envelope2D();
inputPolygonImpl.queryLooseEnvelope2D(env);
env.inflate(tolerance, tolerance);
if (!env.contains(inputPoint))
return 0;
- boolean bAltenate = true;// Path.get_FillMode() == fillmodeAlternate;
+ boolean bAltenate = true;
PointInPolygonHelper helper = new PointInPolygonHelper(bAltenate,
inputPoint, tolerance);
- SegmentIteratorImpl iter = inputPolygonImpl.querySegmentIterator();
- iter.resetToPath(iRing);
- if (iter.nextPath()) {
- while (iter.hasNextSegment()) {
- Segment segment = iter.nextSegment();
- if (helper.processSegment(segment))
- return -1; // point on boundary
+ if (quadTree != null) {
+ Envelope2D queryEnv = new Envelope2D();
+ queryEnv.setCoords(env);
+ queryEnv.xmax = inputPoint.x + tolerance;// no need to query
+ // segments to
+ // the right of the
+ // point.
+ // Only segments to the
+ // left
+ // matter.
+ queryEnv.ymin = inputPoint.y - tolerance;
+ queryEnv.ymax = inputPoint.y + tolerance;
+ SegmentIteratorImpl iter = inputPolygonImpl.querySegmentIterator();
+ QuadTree.QuadTreeIterator qiter = quadTree.getIterator(queryEnv,
+ tolerance);
+
+ for (int qhandle = qiter.next(); qhandle != -1; qhandle = qiter
+ .next()) {
+ iter.resetToVertex(quadTree.getElement(qhandle), iRing);
+ if (iter.hasNextSegment()) {
+ if (iter.getPathIndex() != iRing)
+ continue;
+
+ Segment segment = iter.nextSegment();
+ if (helper.processSegment(segment))
+ return -1; // point on boundary
+ }
}
- }
- return helper.result();
+ return helper.result();
+ } else {
+ SegmentIteratorImpl iter = inputPolygonImpl.querySegmentIterator();
+ iter.resetToPath(iRing);
+
+ if (iter.nextPath()) {
+ while (iter.hasNextSegment()) {
+ Segment segment = iter.nextSegment();
+ if (helper.processSegment(segment))
+ return -1; // point on boundary
+ }
+ }
+
+ return helper.result();
+ }
}
public static int isPointInPolygon(Polygon inputPolygon, Point inputPoint,
@@ -356,4 +387,50 @@ public static int isPointInAnyOuterRing(Polygon inputPolygon,
return helper.result();
}
+ // Tests if Ring1 is inside Ring2.
+ // We assume here that the Polygon is Weak Simple. That is if one point of
+ // Ring1 is found to be inside of Ring2, then
+ // we assume that all of Ring1 is inside Ring2.
+ static boolean _isRingInRing2D(MultiPath polygon, int iRing1, int iRing2,
+ double tolerance, QuadTree quadTree) {
+ MultiPathImpl polygonImpl = (MultiPathImpl) polygon._getImpl();
+ SegmentIteratorImpl segIter = polygonImpl.querySegmentIterator();
+ segIter.resetToPath(iRing1);
+ if (!segIter.nextPath() || !segIter.hasNextSegment())
+ throw new GeometryException("corrupted geometry");
+
+ int res = 2;
+
+ while (res == 2 && segIter.hasNextSegment()) {
+ Segment segment = segIter.nextSegment();
+ Point2D point = segment.getCoord2D(0.5);
+ res = PointInPolygonHelper.isPointInRing(polygonImpl, iRing2,
+ point, tolerance, quadTree);
+ }
+
+ if (res == 2)
+ throw GeometryException.GeometryInternalError();
+ if (res == 1)
+ return true;
+
+ return false;
+ }
+
+ static boolean quadTreeWillHelp(Polygon polygon, int c_queries)
+ {
+ int n = polygon.getPointCount();
+
+ if (n < 16)
+ return false;
+
+ double c_build_quad_tree = 2.0; // what's a good constant?
+ double c_query_quad_tree = 1.0; // what's a good constant?
+ double c_point_in_polygon_brute_force = 1.0; // what's a good constant?
+
+ double c_quad_tree = c_build_quad_tree * n + c_query_quad_tree * (Math.log((double)n) / Math.log(2.0)) * c_queries;
+ double c_brute_force = c_point_in_polygon_brute_force * n * c_queries;
+
+ return c_quad_tree < c_brute_force;
+ }
+
}
diff --git a/src/com/esri/core/geometry/Polygon.java b/src/main/java/com/esri/core/geometry/Polygon.java
similarity index 60%
rename from src/com/esri/core/geometry/Polygon.java
rename to src/main/java/com/esri/core/geometry/Polygon.java
index 18e96249..949a3797 100644
--- a/src/com/esri/core/geometry/Polygon.java
+++ b/src/main/java/com/esri/core/geometry/Polygon.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -27,11 +27,12 @@
import java.io.Serializable;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_POLYGON;
+
/**
* A polygon is a collection of one or many interior or exterior rings.
*/
-public final class Polygon extends MultiPath implements Serializable {
-
+public class Polygon extends MultiPath implements Serializable {
private static final long serialVersionUID = 2L;// TODO:remove as we use
// writeReplace and
// GeometrySerializer
@@ -43,7 +44,7 @@ public Polygon() {
m_impl = new MultiPathImpl(true);
}
- Polygon(VertexDescription vd) {
+ public Polygon(VertexDescription vd) {
m_impl = new MultiPathImpl(true, vd);
}
@@ -62,6 +63,11 @@ public Geometry.Type getType() {
return Type.Polygon;
}
+ @Override
+ public long estimateMemorySize() {
+ return SIZE_OF_POLYGON + m_impl.estimateMemorySize();
+ }
+
/**
* Calculates the ring area for this ring.
*
@@ -73,11 +79,6 @@ public double calculateRingArea2D(int ringIndex) {
return m_impl.calculateRingArea2D(ringIndex);
}
- // FIXME are these a java requirement?
- // int getWKBPolygonCount() { return m_impl.getWKBPolygonCount(); }
- // void setKnownRingOrientation(boolean bYesNo) {
- // m_impl.setKnownRingOrientation(bYesNo); }
-
/**
* Returns TRUE if the ring is an exterior ring. Valid only for simple
* polygons.
@@ -128,13 +129,13 @@ public void setXY(int i, double x, double y) {
}
- void interpolateAttributes(int path_index, int from_point_index,
+ public void interpolateAttributes(int path_index, int from_point_index,
int to_point_index) {
m_impl.interpolateAttributes(path_index, from_point_index,
to_point_index);
}
- void interpolateAttributes(int semantics, int path_index,
+ public void interpolateAttributes(int semantics, int path_index,
int from_point_index, int to_point_index) {
m_impl.interpolateAttributesForSemantics(semantics, path_index,
from_point_index, to_point_index);
@@ -143,5 +144,42 @@ void interpolateAttributes(int semantics, int path_index,
public int getExteriorRingCount() {
return m_impl.getOGCPolygonCount();
}
+
+ public interface FillRule {
+ /**
+ * odd-even fill rule. This is the default value. A point is in the polygon
+ * interior if a ray from this point to infinity crosses odd number of segments
+ * of the polygon.
+ */
+ public final static int enumFillRuleOddEven = 0;
+ /**
+ * winding fill rule (aka non-zero winding rule). A point is in the polygon
+ * interior if a winding number is not zero. To compute a winding number for a
+ * point, draw a ray from this point to infinity. If N is the number of times
+ * the ray crosses segments directed up and the M is the number of times it
+ * crosses segments directed down, then the winding number is equal to N-M.
+ */
+ public final static int enumFillRuleWinding = 1;
+ };
+ /**
+ * Fill rule for the polygon that defines the interior of the self intersecting
+ * polygon. It affects the Simplify operation. Can be use by drawing code to
+ * pass around the fill rule of graphic path. This property is not persisted in
+ * any format yet. See also Polygon.FillRule.
+ */
+ public void setFillRule(int rule) {
+ m_impl.setFillRule(rule);
+ }
+
+ /**
+ * Fill rule for the polygon that defines the interior of the self intersecting
+ * polygon. It affects the Simplify operation. Changing the fill rule on the
+ * polygon that has no self intersections has no physical effect. Can be use by
+ * drawing code to pass around the fill rule of graphic path. This property is
+ * not persisted in any format yet. See also Polygon.FillRule.
+ */
+ public int getFillRule() {
+ return m_impl.getFillRule();
+ }
}
diff --git a/src/com/esri/core/geometry/PolygonUtils.java b/src/main/java/com/esri/core/geometry/PolygonUtils.java
similarity index 73%
rename from src/com/esri/core/geometry/PolygonUtils.java
rename to src/main/java/com/esri/core/geometry/PolygonUtils.java
index 3c5bb5ca..d56f2220 100644
--- a/src/com/esri/core/geometry/PolygonUtils.java
+++ b/src/main/java/com/esri/core/geometry/PolygonUtils.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,9 +24,9 @@
package com.esri.core.geometry;
-class PolygonUtils {
+final class PolygonUtils {
- enum PiPResult {
+ public enum PiPResult {
PiPOutside, PiPInside, PiPBoundary
};
@@ -34,7 +34,7 @@ enum PiPResult {
/**
* Tests if Point is inside the Polygon. Returns PiPOutside if not in
* polygon, PiPInside if in the polygon, PiPBoundary is if on the border. It
- * tests border only if the tolerance is > 0, otherwise PiPBoundary cannot
+ * tests border only if the tolerance is greater than 0, otherwise PiPBoundary cannot
* be returned. Note: If the tolerance is not 0, the test is more expensive
* because it calculates closest distance from a point to each segment.
*
@@ -79,7 +79,7 @@ static PiPResult isPointInPolygon2D(Polygon polygon, double inputPointXVal,
/**
* Tests if Point is inside the Polygon's ring. Returns PiPOutside if not in
* ring, PiPInside if in the ring, PiPBoundary is if on the border. It tests
- * border only if the tolerance is > 0, otherwise PiPBoundary cannot be
+ * border only if the tolerance is greater than 0, otherwise PiPBoundary cannot be
* returned. Note: If the tolerance is not 0, the test is more expensive
* because it calculates closest distance from a point to each segment.
*
@@ -89,7 +89,7 @@ public static PiPResult isPointInRing2D(Polygon polygon, int iRing,
Point2D inputPoint, double tolerance) {
MultiPathImpl polygonImpl = (MultiPathImpl) polygon._getImpl();
int res = PointInPolygonHelper.isPointInRing(polygonImpl, iRing,
- inputPoint, tolerance);
+ inputPoint, tolerance, null);
if (res == 0)
return PiPResult.PiPOutside;
if (res == 1)
@@ -127,33 +127,10 @@ public static PiPResult isPointInAnyOuterRing(Polygon polygon,
// internal and external boundaries.
}
- // #ifndef DOTNET
- // /**
- // *Tests point is inside the Polygon for an array of points.
- // *Returns PiPOutside if not in polygon, PiPInside if in the polygon,
- // PiPBoundary is if on the border.
- // *It tests border only if the tolerance is > 0, otherwise PiPBoundary
- // cannot be returned.
- // *Note: If the tolerance is not 0, the test is more expensive.
- // *
- // *O(n*m) complexity, where n is the number of polygon segments, m is the
- // number of input points.
- // */
- // static void TestPointsInPolygon2D(Polygon polygon, const Point2D*
- // inputPoints, int count, double tolerance, PiPResult testResults)
- // {
- // LOCALREFCLASS2(Array, Point2D*, int, inputPointsArr,
- // const_cast(inputPoints), count);
- // LOCALREFCLASS2(Array, PolygonUtils::PiPResult*,
- // int, testResultsArr, testResults, count);
- // TestPointsInPolygon2D(polygon, inputPointsArr, count, tolerance,
- // testResultsArr);
- // }
- // #endif
/**
* Tests point is inside the Polygon for an array of points. Returns
* PiPOutside if not in polygon, PiPInside if in the polygon, PiPBoundary is
- * if on the border. It tests border only if the tolerance is > 0, otherwise
+ * if on the border. It tests border only if the tolerance is greater than 0, otherwise
* PiPBoundary cannot be returned. Note: If the tolerance is not 0, the test
* is more expensive.
*
@@ -182,31 +159,11 @@ static void testPointsInPolygon2D(Polygon polygon, double[] xyStreamBuffer,
xyStreamBuffer[i * 2 + 1], tolerance);
}
- // public static void testPointsInPolygon2D(Polygon polygon, Geometry geom,
- // int count, double tolerance, PiPResult[] testResults)
- // {
- // if(geom.getType() == Type.Point)
- // {
- //
- // }
- // else if(Geometry.isMultiVertex(geom.getType()))
- // {
- //
- // }
- //
- //
- // if (inputPoints.length < count || testResults.length < count)
- // throw new IllegalArgumentException();//GEOMTHROW(invalid_argument);
- //
- // for (int i = 0; i < count; i++)
- // testResults[i] = isPointInPolygon2D(polygon, inputPoints[i], tolerance);
- // }
-
/**
* Tests point is inside an Area Geometry (Envelope, Polygon) for an array
* of points. Returns PiPOutside if not in area, PiPInside if in the area,
* PiPBoundary is if on the border. It tests border only if the tolerance is
- * > 0, otherwise PiPBoundary cannot be returned. Note: If the tolerance is
+ * greater than 0, otherwise PiPBoundary cannot be returned. Note: If the tolerance is
* not 0, the test is more expensive.
*
* O(n*m) complexity, where n is the number of polygon segments, m is the
@@ -242,38 +199,6 @@ else if (polygon.getType() == Geometry.Type.Envelope) {
throw new GeometryException("invalid_call");// GEOMTHROW(invalid_call);
}
- // Tests if Ring1 is inside Ring2.
- // We assume here that the Polygon is Weak Simple. That is if one point of
- // Ring1 is found to be inside of Ring2, then
- // we assume that all of Ring1 is inside Ring2.
- static boolean _isRingInRing2D(MultiPathImpl polygonImpl, int iRing1,
- int iRing2, double tolerance) {
- SegmentIteratorImpl segIter = polygonImpl.querySegmentIterator();
- segIter.resetToPath(iRing1);
- if (!segIter.nextPath() || !segIter.hasNextSegment())
- throw new GeometryException("corrupted geometry");
-
- // FIXME java enums can't cast to ints? what the hell?!
- // enum_class PiPResult { PiPOutside = 0, PiPInside = 1, PiPBoundary =
- // 2};
- int res = 2;// 2(int)PiPResult.PiPBoundary;
-
- while (res == 2 /* (int)PiPResult.PiPBoundary */
- && segIter.hasNextSegment()) {
- Segment segment = segIter.nextSegment();
- Point2D point = segment.getCoord2D(0.5);
- res = PointInPolygonHelper.isPointInRing(polygonImpl, iRing2,
- point, tolerance);
- }
-
- if (res == 2 /* (int)PiPResult.PiPBoundary */)
- throw new GeometryException("internal error");
- if (res == 1 /* (int)PiPResult.PiPInside */)
- return true;
-
- return false;
- }
-
private static void _testPointsInEnvelope2D(Envelope2D env2D,
Point2D[] inputPoints, int count, double tolerance,
PiPResult[] testResults) {
@@ -400,28 +325,4 @@ else if (Geometry.isSegment(gt.value())) {
throw new GeometryException("Invalid call.");
}
- /*
- * // Tests if Ring1 is inside Ring2. // We assume here that the Polygon is
- * Weak Simple. That is if one point of Ring1 is found to be inside of
- * Ring2, then // we assume that all of Ring1 is inside Ring2. public static
- * booleanean _isRingInRing2D(MultiPathImpl polygonImpl, int iRing1, int
- * iRing2, double tolerance) { SegmentIteratorImpl segIter =
- * polygonImpl.querySegmentIterator(); segIter.resetToPath(iRing1); if
- * (!segIter.nextPath() || !segIter.hasNextSegment()) throw new
- * GeometryException("corrupted geometry");
- *
- * PiPResult res = PiPResult.PiPBoundary;
- *
- * while ((res == PiPResult.PiPBoundary) && segIter.hasNextSegment()) {
- * Segment segment = segIter.nextSegment(); Point2D point =
- * segment.getCoord2D(0.5); res =
- * PointInPolygonHelper.isPointInRing(polygonImpl, iRing2, point,
- * tolerance); }
- *
- * if (res == PiPResult. PiPBoundary) throw new
- * GeometryException("internal error"); if (res == PiPResult.PiPInside)
- * return true;
- *
- * return false; }
- */
}
diff --git a/src/com/esri/core/geometry/Polyline.java b/src/main/java/com/esri/core/geometry/Polyline.java
similarity index 77%
rename from src/com/esri/core/geometry/Polyline.java
rename to src/main/java/com/esri/core/geometry/Polyline.java
index 194bbfb6..9f45d7ea 100644
--- a/src/com/esri/core/geometry/Polyline.java
+++ b/src/main/java/com/esri/core/geometry/Polyline.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -27,11 +27,13 @@
import java.io.Serializable;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_POLYLINE;
+
/**
* A polyline is a collection of one or many paths.
*
*/
-public final class Polyline extends MultiPath implements Serializable {
+public class Polyline extends MultiPath implements Serializable {
private static final long serialVersionUID = 2L;// TODO:remove as we use
// writeReplace and
@@ -44,10 +46,19 @@ public Polyline() {
m_impl = new MultiPathImpl(false);
}
- Polyline(VertexDescription vd) {
+ public Polyline(VertexDescription vd) {
m_impl = new MultiPathImpl(false, vd);
}
+ /**
+ * Creates a polyline with one line segment.
+ */
+ public Polyline(Point start, Point end) {
+ m_impl = new MultiPathImpl(false, start.getDescription());
+ startPath(start);
+ lineTo(end);
+ }
+
@Override
public Geometry createInstance() {
return new Polyline(getDescription());
@@ -63,6 +74,11 @@ public Geometry.Type getType() {
return Type.Polyline;
}
+ @Override
+ public long estimateMemorySize() {
+ return SIZE_OF_POLYLINE + m_impl.estimateMemorySize();
+ }
+
/**
* Returns TRUE when this geometry has exactly same type, properties, and
* coordinates as the other geometry.
@@ -95,13 +111,13 @@ public void addSegment(Segment segment, boolean bStartNewPath) {
m_impl.addSegment(segment, bStartNewPath);
}
- void interpolateAttributes(int from_path_index, int from_point_index,
- int to_path_index, int to_point_index) {
+ public void interpolateAttributes(int from_path_index,
+ int from_point_index, int to_path_index, int to_point_index) {
m_impl.interpolateAttributes(from_path_index, from_point_index,
to_path_index, to_point_index);
}
- void interpolateAttributes(int semantics, int from_path_index,
+ public void interpolateAttributes(int semantics, int from_path_index,
int from_point_index, int to_path_index, int to_point_index) {
m_impl.interpolateAttributesForSemantics(semantics, from_path_index,
from_point_index, to_path_index, to_point_index);
diff --git a/src/com/esri/core/geometry/ProgressTracker.java b/src/main/java/com/esri/core/geometry/ProgressTracker.java
similarity index 79%
rename from src/com/esri/core/geometry/ProgressTracker.java
rename to src/main/java/com/esri/core/geometry/ProgressTracker.java
index d185b991..09933688 100644
--- a/src/com/esri/core/geometry/ProgressTracker.java
+++ b/src/main/java/com/esri/core/geometry/ProgressTracker.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,4 +34,13 @@ public abstract class ProgressTracker {
*@return true, if the operation can continue. Returns False, when the operation has to terminate due to a user cancelation.
*/
public abstract boolean progress(int step, int totalExpectedSteps);
+
+ /**
+ * Checks the tracker and throws UserCancelException if tracker is not null and progress returns false
+ * @param tracker can be null, then the method does nothing.
+ */
+ public static void checkAndThrow(ProgressTracker tracker) {
+ if (tracker != null && !tracker.progress(-1, -1))
+ throw new UserCancelException();
+ }
}
diff --git a/src/com/esri/core/geometry/ProjectionTransformation.java b/src/main/java/com/esri/core/geometry/ProjectionTransformation.java
similarity index 96%
rename from src/com/esri/core/geometry/ProjectionTransformation.java
rename to src/main/java/com/esri/core/geometry/ProjectionTransformation.java
index 4f2aedde..858bc03c 100644
--- a/src/com/esri/core/geometry/ProjectionTransformation.java
+++ b/src/main/java/com/esri/core/geometry/ProjectionTransformation.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/Proximity2DResult.java b/src/main/java/com/esri/core/geometry/Proximity2DResult.java
similarity index 78%
rename from src/com/esri/core/geometry/Proximity2DResult.java
rename to src/main/java/com/esri/core/geometry/Proximity2DResult.java
index 01a1a2ae..0e1efe71 100644
--- a/src/com/esri/core/geometry/Proximity2DResult.java
+++ b/src/main/java/com/esri/core/geometry/Proximity2DResult.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -32,6 +32,21 @@ public class Proximity2DResult {
Point2D m_coordinate = new Point2D();
int m_vertexIndex;
double m_distance;
+ int m_info;
+
+ /**
+ * Sets the right_side info to true or false.
+ *
+ * @param bRight
+ * Whether the nearest coordinate is to the right or left of the
+ * geometry.
+ */
+ public void setRightSide(boolean bRight) {
+ if (bRight)
+ m_info |= (int) OperatorProximity2D.ProxResultInfo.rightSide;
+ else
+ m_info &= ~(int) OperatorProximity2D.ProxResultInfo.rightSide;
+ }
/**
* Returns TRUE if the Proximity2DResult is empty. This only happens if the
@@ -81,6 +96,13 @@ public double getDistance() {
return m_distance;
}
+ /**
+ *Returns true if the closest coordinate is to the right of the MultiPath.
+ */
+ public boolean isRightSide() {
+ return (m_info & (int) OperatorProximity2D.ProxResultInfo.rightSide) != 0;
+ }
+
void _setParams(double x, double y, int vertexIndex, double distance) {
m_coordinate.x = x;
m_coordinate.y = y;
@@ -101,4 +123,11 @@ void _setParams(double x, double y, int vertexIndex, double distance) {
Proximity2DResult() {
m_vertexIndex = -1;
}
+
+ Proximity2DResult(Point2D coordinate, int vertexIndex, double distance) {
+ m_coordinate.setCoords(coordinate);
+ m_vertexIndex = vertexIndex;
+ m_distance = distance;
+ m_info = 0;
+ }
}
diff --git a/src/com/esri/core/geometry/Proximity2DResultComparator.java b/src/main/java/com/esri/core/geometry/Proximity2DResultComparator.java
similarity index 97%
rename from src/com/esri/core/geometry/Proximity2DResultComparator.java
rename to src/main/java/com/esri/core/geometry/Proximity2DResultComparator.java
index 1be0cfbb..0404aa80 100644
--- a/src/com/esri/core/geometry/Proximity2DResultComparator.java
+++ b/src/main/java/com/esri/core/geometry/Proximity2DResultComparator.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/PtSrlzr.java b/src/main/java/com/esri/core/geometry/PtSrlzr.java
new file mode 100644
index 00000000..68dd1aae
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/PtSrlzr.java
@@ -0,0 +1,88 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+//This is a writeReplace class for Point
+public class PtSrlzr implements Serializable {
+ private static final long serialVersionUID = 1L;
+ double[] attribs;
+ int descriptionBitMask;
+
+ public Object readResolve() throws ObjectStreamException {
+ Point point = null;
+ try {
+ VertexDescription vd = VertexDescriptionDesignerImpl
+ .getVertexDescription(descriptionBitMask);
+ point = new Point(vd);
+ if (attribs != null) {
+ point.setXY(attribs[0], attribs[1]);
+ int index = 2;
+ for (int i = 1, n = vd.getAttributeCount(); i < n; i++) {
+ int semantics = vd.getSemantics(i);
+ int comps = VertexDescription.getComponentCount(semantics);
+ for (int ord = 0; ord < comps; ord++) {
+ point.setAttribute(semantics, ord, attribs[index++]);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot read geometry from stream");
+ }
+
+ return point;
+ }
+
+ public void setGeometryByValue(Point point) throws ObjectStreamException {
+ try {
+ attribs = null;
+ if (point == null) {
+ descriptionBitMask = 1;
+ }
+
+ VertexDescription vd = point.getDescription();
+ descriptionBitMask = vd.m_semanticsBitArray;
+ if (point.isEmpty()) {
+ return;
+ }
+
+ attribs = new double[vd.getTotalComponentCount()];
+ attribs[0] = point.getX();
+ attribs[1] = point.getY();
+ int index = 2;
+ for (int i = 1, n = vd.getAttributeCount(); i < n; i++) {
+ int semantics = vd.getSemantics(i);
+ int comps = VertexDescription.getComponentCount(semantics);
+ for (int ord = 0; ord < comps; ord++) {
+ attribs[index++] = point.getAttributeAsDbl(semantics, ord);
+ }
+ }
+ } catch (Exception ex) {
+ throw new InvalidObjectException("Cannot serialize this geometry");
+ }
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/QuadTree.java b/src/main/java/com/esri/core/geometry/QuadTree.java
new file mode 100644
index 00000000..0b4a4945
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/QuadTree.java
@@ -0,0 +1,344 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+
+package com.esri.core.geometry;
+
+import java.io.Serializable;
+
+public class QuadTree implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public static final class QuadTreeIterator {
+ /**
+ * Resets the iterator to an starting state on the QuadTree. If the
+ * input Geometry is a Line segment, then the query will be the segment.
+ * Otherwise the query will be the Envelope2D bounding the Geometry.
+ * \param query The Geometry used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ public void resetIterator(Geometry query, double tolerance) {
+ if (!m_b_sorted)
+ ((QuadTreeImpl.QuadTreeIteratorImpl) m_impl).resetIterator(query, tolerance);
+ else
+ ((QuadTreeImpl.QuadTreeSortedIteratorImpl) m_impl).resetIterator(query, tolerance);
+ }
+
+ /**
+ * Resets the iterator to a starting state on the QuadTree using the
+ * input Envelope2D as the query.
+ * \param query The Envelope2D used for the query.
+ * \param tolerance The tolerance used for the intersection
+ * tests.
+ */
+ public void resetIterator(Envelope2D query, double tolerance) {
+ if (!m_b_sorted)
+ ((QuadTreeImpl.QuadTreeIteratorImpl) m_impl).resetIterator(query, tolerance);
+ else
+ ((QuadTreeImpl.QuadTreeSortedIteratorImpl) m_impl).resetIterator(query, tolerance);
+ }
+
+ /**
+ * Moves the iterator to the next Element_handle and returns the
+ * Element_handle.
+ */
+ public int next() {
+ if (!m_b_sorted)
+ return ((QuadTreeImpl.QuadTreeIteratorImpl) m_impl).next();
+ else
+ return ((QuadTreeImpl.QuadTreeSortedIteratorImpl) m_impl).next();
+ }
+
+ /**
+ * Returns a void* to the impl class.
+ */
+ Object getImpl_() {
+ return m_impl;
+ }
+
+ // Creates an iterator on the input QuadTreeImpl. The query will be
+ // the Envelope2D bounding the input Geometry.
+ private QuadTreeIterator(Object obj, boolean bSorted) {
+
+ m_impl = obj;
+ m_b_sorted = bSorted;
+ }
+
+ private Object m_impl;
+ private boolean m_b_sorted;
+ }
+
+ /**
+ * Creates a QuadTree with the root having the extent of the input
+ * Envelope2D, and height of the input height, where the root starts at height 0.
+ * \param extent The extent of the QuadTree.
+ * \param height The max height of the QuadTree.
+ */
+ public QuadTree(Envelope2D extent, int height) {
+ m_impl = new QuadTreeImpl(extent, height);
+ }
+
+ /**
+ * Creates a QuadTree with the root having the extent of the input Envelope2D, and height of the input height, where the root starts at height 0.
+ * \param extent The extent of the QuadTreeImpl.
+ * \param height The max height of the QuadTreeImpl.
+ * \param bStoreDuplicates Put true to place elements deeper into the quad tree at intesecting quads, duplicates will be stored. Put false to only place elements into quads that can contain it..
+ */
+ public QuadTree(Envelope2D extent, int height, boolean bStoreDuplicates) {
+ m_impl = new QuadTreeImpl(extent, height, bStoreDuplicates);
+ }
+
+ /**
+ * Inserts the element and bounding_box into the QuadTree. Note that a copy
+ * will me made of the input bounding_box. Note that this will invalidate
+ * any active iterator on the QuadTree. Returns an Element_handle
+ * corresponding to the element and bounding_box.
+ * \param element The element of the Geometry to be inserted.
+ * \param bounding_box The bounding_box of
+ * the Geometry to be inserted.
+ */
+ public int insert(int element, Envelope2D boundingBox) {
+ return m_impl.insert(element, boundingBox);
+ }
+
+ /**
+ * Inserts the element and bounding_box into the QuadTree at the given
+ * quad_handle. Note that a copy will me made of the input bounding_box.
+ * Note that this will invalidate any active iterator on the QuadTree.
+ * Returns an Element_handle corresponding to the element and bounding_box.
+ * \param element The element of the Geometry to be inserted.
+ * \param bounding_box The bounding_box of the Geometry to be inserted.
+ * \param hint_index A handle used as a hint where to place the element. This can
+ * be a handle obtained from a previous insertion and is useful on data
+ * having strong locality such as segments of a Polygon.
+ */
+ public int insert(int element, Envelope2D boundingBox, int hintIndex) {
+ return m_impl.insert(element, boundingBox, hintIndex);
+ }
+
+ /**
+ * Removes the element and bounding_box at the given element_handle. Note
+ * that this will invalidate any active iterator on the QuadTree.
+ * \param element_handle The handle corresponding to the element and bounding_box
+ * to be removed.
+ */
+ public void removeElement(int elementHandle) {
+ m_impl.removeElement(elementHandle);
+ }
+
+ /**
+ * Returns the element at the given element_handle.
+ * \param element_handle The handle corresponding to the element to be retrieved.
+ */
+ public int getElement(int elementHandle) {
+ return m_impl.getElement(elementHandle);
+ }
+
+ /**
+ * Returns the element extent at the given element_handle.
+ * \param element_handle The handle corresponding to the element extent to be retrieved.
+ */
+ public Envelope2D getElementExtent(int elementHandle) {
+ return m_impl.getElementExtent(elementHandle);
+ }
+
+ /**
+ * Returns the extent of all elements in the quad tree.
+ */
+ public Envelope2D getDataExtent() {
+ return m_impl.getDataExtent();
+ }
+
+ /**
+ * Returns the extent of the quad tree.
+ */
+ public Envelope2D getQuadTreeExtent() {
+ return m_impl.getQuadTreeExtent();
+ }
+
+ /**
+ * Returns the number of elements in the subtree rooted at the given quad_handle.
+ * \param quad_handle The handle corresponding to the quad.
+ */
+ public int getSubTreeElementCount(int quadHandle) {
+ return m_impl.getSubTreeElementCount(quadHandle);
+ }
+
+ /**
+ * Returns the number of elements contained in the subtree rooted at the given quad_handle.
+ * \param quad_handle The handle corresponding to the quad.
+ */
+ public int getContainedSubTreeElementCount(int quadHandle) {
+ return m_impl.getContainedSubTreeElementCount(quadHandle);
+ }
+
+ /**
+ * Returns the number of elements in the quad tree that intersect the qiven query. Some elements may be duplicated if the quad tree stores duplicates.
+ * \param query The Envelope2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ * \param max_count If the intersection count becomes greater than or equal to the max_count, then max_count is returned.
+ */
+ public int getIntersectionCount(Envelope2D query, double tolerance, int maxCount) {
+ return m_impl.getIntersectionCount(query, tolerance, maxCount);
+ }
+
+ /**
+ * Returns true if the quad tree has data intersecting the given query.
+ * \param query The Envelope2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ public boolean hasData(Envelope2D query, double tolerance) {
+ return m_impl.hasData(query, tolerance);
+ }
+
+ /**
+ * Returns the height of the quad at the given quad_handle. \param
+ * quad_handle The handle corresponding to the quad.
+ */
+ public int getHeight(int quadHandle) {
+ return m_impl.getHeight(quadHandle);
+ }
+
+ /**
+ * Returns the max height the quad tree can grow to.
+ */
+ public int getMaxHeight() {
+ return m_impl.getMaxHeight();
+ }
+
+ /**
+ * Returns the extent of the quad at the given quad_handle.
+ * \param quad_handle The handle corresponding to the quad.
+ */
+ public Envelope2D getExtent(int quadHandle) {
+ return m_impl.getExtent(quadHandle);
+ }
+
+ /**
+ * Returns the Quad_handle of the quad containing the given element_handle.
+ * \param element_handle The handle corresponding to the element.
+ */
+ public int getQuad(int elementHandle) {
+ return m_impl.getQuad(elementHandle);
+ }
+
+ /**
+ * Returns the number of elements in the QuadTree.
+ */
+ public int getElementCount() {
+ return m_impl.getElementCount();
+ }
+
+ /**
+ * Gets an iterator on the QuadTree. The query will be the Envelope2D that
+ * bounds the input Geometry. To reuse the existing iterator on the same
+ * QuadTree but with a new query, use the reset_iterator function on the
+ * QuadTree_iterator.
+ * \param query The Geometry used for the query. If the
+ * Geometry is a Line segment, then the query will be the segment. Otherwise
+ * the query will be the Envelope2D bounding the Geometry.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ public QuadTreeIterator getIterator(Geometry query, double tolerance) {
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, false);
+ }
+
+ /**
+ * Gets an iterator on the QuadTree using the input Envelope2D as the
+ * query. To reuse the existing iterator on the same QuadTree but with a
+ * new query, use the reset_iterator function on the QuadTree_iterator.
+ * \param query The Envelope2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ public QuadTreeIterator getIterator(Envelope2D query, double tolerance) {
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, false);
+ }
+
+ /**
+ * Gets an iterator on the QuadTree.
+ */
+ public QuadTreeIterator getIterator() {
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator();
+ return new QuadTreeIterator(iterator, false);
+ }
+
+ /**
+ * Gets an iterator on the QuadTree. The query will be the Envelope2D that bounds the input Geometry.
+ * To reuse the existing iterator on the same QuadTree but with a new query, use the reset_iterator function on the QuadTree_iterator.
+ * \param query The Geometry used for the query. If the Geometry is a Line segment, then the query will be the segment. Otherwise the query will be the Envelope2D bounding the Geometry.
+ * \param tolerance The tolerance used for the intersection tests.
+ * \param bSorted Put true to iterate the quad tree in the order of the Element_types.
+ */
+ public QuadTreeIterator getIterator(Geometry query, double tolerance, boolean bSorted) {
+ if (!bSorted) {
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, false);
+ } else {
+ QuadTreeImpl.QuadTreeSortedIteratorImpl iterator = m_impl.getSortedIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, true);
+ }
+ }
+
+ /**
+ * Gets an iterator on the QuadTree using the input Envelope2D as the query.
+ * To reuse the existing iterator on the same QuadTree but with a new query, use the reset_iterator function on the QuadTree_iterator.
+ * \param query The Envelope2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ * \param bSorted Put true to iterate the quad tree in the order of the Element_types.
+ */
+ public QuadTreeIterator getIterator(Envelope2D query, double tolerance, boolean bSorted) {
+ if (!bSorted) {
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, false);
+ } else {
+ QuadTreeImpl.QuadTreeSortedIteratorImpl iterator = m_impl.getSortedIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, true);
+ }
+ }
+
+ /**
+ * Gets an iterator on the QuadTree.
+ * \param bSorted Put true to iterate the quad tree in the order of the Element_types.
+ */
+ public QuadTreeIterator getIterator(boolean bSorted) {
+ if (!bSorted) {
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator();
+ return new QuadTreeIterator(iterator, false);
+ } else {
+ QuadTreeImpl.QuadTreeSortedIteratorImpl iterator = m_impl.getSortedIterator();
+ return new QuadTreeIterator(iterator, true);
+ }
+ }
+
+ /**
+ * Returns a void* to the impl class.
+ */
+ Object getImpl_() {
+ return m_impl;
+ }
+
+ private QuadTreeImpl m_impl;
+}
diff --git a/src/main/java/com/esri/core/geometry/QuadTreeImpl.java b/src/main/java/com/esri/core/geometry/QuadTreeImpl.java
new file mode 100644
index 00000000..e9234bb5
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/QuadTreeImpl.java
@@ -0,0 +1,1380 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_DATA;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_QUAD_TREE_IMPL;
+import static com.esri.core.geometry.SizeOf.sizeOfObjectArray;
+
+class QuadTreeImpl implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ static final class QuadTreeIteratorImpl {
+ /**
+ * Resets the iterator to an starting state on the Quad_tree_impl. If
+ * the input Geometry is a Line segment, then the query will be the
+ * segment. Otherwise the query will be the Envelope_2D bounding the
+ * Geometry. \param query The Geometry used for the query. \param
+ * tolerance The tolerance used for the intersection tests. \param
+ * tolerance The tolerance used for the intersection tests.
+ */
+ void resetIterator(Geometry query, double tolerance) {
+ m_quads_stack.resize(0);
+ m_extents_stack.clear();
+ m_current_element_handle = -1;
+ query.queryLooseEnvelope2D(m_query_box);
+ m_query_box.inflate(tolerance, tolerance);
+
+ if (m_quad_tree.m_root != -1 && m_query_box.isIntersecting(m_quad_tree.m_extent)) {
+ int type = query.getType().value();
+ m_b_linear = Geometry.isSegment(type);
+
+ if (m_b_linear) {
+ Segment segment = (Segment) query;
+ m_query_start = segment.getStartXY();
+ m_query_end = segment.getEndXY();
+ m_tolerance = tolerance;
+ } else {
+ m_tolerance = NumberUtils.NaN(); // we don't need it
+ }
+
+ m_quads_stack.add(m_quad_tree.m_root);
+ m_extents_stack.add(m_quad_tree.m_extent);
+ m_next_element_handle = m_quad_tree.get_first_element_(m_quad_tree.m_root);
+ } else
+ m_next_element_handle = -1;
+ }
+
+ /**
+ * Resets the iterator to a starting state on the Quad_tree_impl using
+ * the input Envelope_2D as the query. \param query The Envelope_2D used
+ * for the query. \param tolerance The tolerance used for the
+ * intersection tests.
+ */
+ void resetIterator(Envelope2D query, double tolerance) {
+ m_quads_stack.resize(0);
+ m_extents_stack.clear();
+ m_current_element_handle = -1;
+ m_query_box.setCoords(query);
+ m_query_box.inflate(tolerance, tolerance);
+ m_tolerance = NumberUtils.NaN(); // we don't need it
+
+ if (m_quad_tree.m_root != -1 && m_query_box.isIntersecting(m_quad_tree.m_extent)) {
+ m_quads_stack.add(m_quad_tree.m_root);
+ m_extents_stack.add(m_quad_tree.m_extent);
+ m_next_element_handle = m_quad_tree.get_first_element_(m_quad_tree.m_root);
+ m_b_linear = false;
+ } else
+ m_next_element_handle = -1;
+ }
+
+ /**
+ * Moves the iterator to the next int and returns the int.
+ */
+ int next() {
+ // If the node stack is empty, then we've exhausted our search
+
+ if (m_quads_stack.size() == 0)
+ return -1;
+
+ m_current_element_handle = m_next_element_handle;
+
+ Point2D start = null;
+ Point2D end = null;
+ Envelope2D bounding_box;
+ Envelope2D extent_inf = null;
+ Envelope2D[] child_extents = null;
+
+ if (m_b_linear) {
+ start = new Point2D();
+ end = new Point2D();
+ extent_inf = new Envelope2D();
+ }
+
+ boolean b_found_hit = false;
+ while (!b_found_hit) {
+ while (m_current_element_handle != -1) {
+ int current_data_handle = m_quad_tree.get_data_(m_current_element_handle);
+ bounding_box = m_quad_tree.get_bounding_box_value_(current_data_handle);
+
+ if (bounding_box.isIntersecting(m_query_box)) {
+ if (m_b_linear) {
+ start.setCoords(m_query_start);
+ end.setCoords(m_query_end);
+ extent_inf.setCoords(bounding_box);
+
+ extent_inf.inflate(m_tolerance, m_tolerance);
+ if (extent_inf.clipLine(start, end) > 0) {
+ b_found_hit = true;
+ break;
+ }
+ } else {
+ b_found_hit = true;
+ break;
+ }
+ }
+
+ // get next element_handle
+ m_current_element_handle = m_quad_tree.get_next_element_(m_current_element_handle);
+ }
+
+ // If m_current_element_handle equals -1, then we've exhausted our search in the current quadtree node
+ if (m_current_element_handle == -1) {
+ // get the last node from the stack and add the children whose extent intersects m_query_box
+ int current_quad = m_quads_stack.getLast();
+ Envelope2D current_extent = m_extents_stack.get(m_extents_stack.size() - 1);
+
+ if (child_extents == null) {
+ child_extents = new Envelope2D[4];
+ child_extents[0] = new Envelope2D();
+ child_extents[1] = new Envelope2D();
+ child_extents[2] = new Envelope2D();
+ child_extents[3] = new Envelope2D();
+ }
+
+ set_child_extents_(current_extent, child_extents);
+ m_quads_stack.removeLast();
+ m_extents_stack.remove(m_extents_stack.size() - 1);
+
+ for (int quadrant = 0; quadrant < 4; quadrant++) {
+ int child_handle = m_quad_tree.get_child_(current_quad, quadrant);
+
+ if (child_handle != -1 && m_quad_tree.getSubTreeElementCount(child_handle) > 0) {
+ if (child_extents[quadrant].isIntersecting(m_query_box)) {
+ if (m_b_linear) {
+ start.setCoords(m_query_start);
+ end.setCoords(m_query_end);
+
+ extent_inf.setCoords(child_extents[quadrant]);
+ extent_inf.inflate(m_tolerance, m_tolerance);
+ if (extent_inf.clipLine(start, end) > 0) {
+ Envelope2D child_extent = new Envelope2D();
+ child_extent.setCoords(child_extents[quadrant]);
+ m_quads_stack.add(child_handle);
+ m_extents_stack.add(child_extent);
+ }
+ } else {
+ Envelope2D child_extent = new Envelope2D();
+ child_extent.setCoords(child_extents[quadrant]);
+ m_quads_stack.add(child_handle);
+ m_extents_stack.add(child_extent);
+ }
+ }
+ }
+ }
+
+ assert (m_quads_stack.size() <= 4 * (m_quad_tree.m_height - 1));
+
+ if (m_quads_stack.size() == 0)
+ return -1;
+
+ m_current_element_handle = m_quad_tree.get_first_element_(m_quads_stack.get(m_quads_stack.size() - 1));
+ }
+ }
+
+ // We did not exhaust our search in the current node, so we return
+ // the element at m_current_element_handle in m_element_nodes
+
+ m_next_element_handle = m_quad_tree.get_next_element_(m_current_element_handle);
+ return m_current_element_handle;
+ }
+
+ // Creates an iterator on the input Quad_tree_impl. The query will be
+ // the Envelope_2D bounding the input Geometry.
+ QuadTreeIteratorImpl(QuadTreeImpl quad_tree_impl, Geometry query, double tolerance) {
+ m_quad_tree = quad_tree_impl;
+ m_query_box = new Envelope2D();
+ m_quads_stack = new AttributeStreamOfInt32(0);
+ m_extents_stack = new ArrayList(0);
+ resetIterator(query, tolerance);
+ }
+
+ // Creates an iterator on the input Quad_tree_impl using the input
+ // Envelope_2D as the query.
+ QuadTreeIteratorImpl(QuadTreeImpl quad_tree_impl, Envelope2D query, double tolerance) {
+ m_quad_tree = quad_tree_impl;
+ m_query_box = new Envelope2D();
+ m_quads_stack = new AttributeStreamOfInt32(0);
+ m_extents_stack = new ArrayList(0);
+ resetIterator(query, tolerance);
+ }
+
+ // Creates an iterator on the input Quad_tree_impl.
+ QuadTreeIteratorImpl(QuadTreeImpl quad_tree_impl) {
+ m_quad_tree = quad_tree_impl;
+ m_query_box = new Envelope2D();
+ m_quads_stack = new AttributeStreamOfInt32(0);
+ m_extents_stack = new ArrayList(0);
+ }
+
+ private boolean m_b_linear;
+ private Point2D m_query_start;
+ private Point2D m_query_end;
+ private Envelope2D m_query_box;
+ private double m_tolerance;
+ private int m_current_element_handle;
+ private int m_next_element_handle;
+ private QuadTreeImpl m_quad_tree;
+ private AttributeStreamOfInt32 m_quads_stack;
+ private ArrayList m_extents_stack; // this won't grow bigger than 4 * (m_quad_tree->m_height - 1)
+ }
+
+ static final class QuadTreeSortedIteratorImpl {
+ /**
+ * Resets the iterator to a starting state on the Quad_tree_impl. If the input Geometry is a Line segment, then the query will be the segment. Otherwise the query will be the Envelope_2D bounding the Geometry.
+ * \param query The Geometry used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ void resetIterator(Geometry query, double tolerance) {
+ m_quad_tree_iterator_impl.resetIterator(query, tolerance);
+ m_sorted_handles.resize(0);
+ m_index = -1;
+ }
+
+ /**
+ * Resets the iterator to a starting state on the Quad_tree_impl using the input Envelope_2D as the query.
+ * \param query The Envelope_2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ void resetIterator(Envelope2D query, double tolerance) {
+ m_quad_tree_iterator_impl.resetIterator(query, tolerance);
+ m_sorted_handles.resize(0);
+ m_index = -1;
+ }
+
+ /**
+ * Moves the iterator to the next Element_handle and returns the Element_handle.
+ */
+ int next() {
+ if (m_index == -1) {
+ int element_handle = -1;
+ while ((element_handle = m_quad_tree_iterator_impl.next()) != -1)
+ m_sorted_handles.add(element_handle);
+
+ m_bucket_sort.sort(m_sorted_handles, 0, m_sorted_handles.size(), new Sorter(m_quad_tree_iterator_impl.m_quad_tree));
+ }
+
+ if (m_index == m_sorted_handles.size() - 1)
+ return -1;
+
+ m_index++;
+ return m_sorted_handles.get(m_index);
+ }
+
+ //Creates a sorted iterator on the input Quad_tree_iterator_impl
+ QuadTreeSortedIteratorImpl(QuadTreeIteratorImpl quad_tree_iterator_impl) {
+ m_bucket_sort = new BucketSort();
+ m_sorted_handles = new AttributeStreamOfInt32(0);
+ m_quad_tree_iterator_impl = quad_tree_iterator_impl;
+ m_index = -1;
+ }
+
+ private class Sorter extends ClassicSort {
+ public Sorter(QuadTreeImpl quad_tree) {
+ m_quad_tree = quad_tree;
+ }
+
+ @Override
+ public void userSort(int begin, int end, AttributeStreamOfInt32 indices) {
+ indices.sort(begin, end);
+ }
+
+ @Override
+ public double getValue(int e) {
+ return m_quad_tree.getElement(e);
+ }
+
+ private QuadTreeImpl m_quad_tree;
+ }
+
+ private BucketSort m_bucket_sort;
+ private AttributeStreamOfInt32 m_sorted_handles;
+ private QuadTreeIteratorImpl m_quad_tree_iterator_impl;
+ int m_index;
+ }
+
+ /**
+ * Creates a Quad_tree_impl with the root having the extent of the input Envelope_2D, and height of the input height, where the root starts at height 0.
+ * \param extent The extent of the Quad_tree_impl.
+ * \param height The max height of the Quad_tree_impl.
+ */
+ QuadTreeImpl(Envelope2D extent, int height) {
+ m_quad_tree_nodes = new StridedIndexTypeCollection(10);
+ m_element_nodes = new StridedIndexTypeCollection(4);
+ m_data = new ArrayList(0);
+ m_free_data = new AttributeStreamOfInt32(0);
+ m_b_store_duplicates = false;
+
+ m_extent = new Envelope2D();
+ m_data_extent = new Envelope2D();
+
+ reset_(extent, height);
+ }
+
+ /**
+ * Creates a Quad_tree_impl with the root having the extent of the input Envelope_2D, and height of the input height, where the root starts at height 0.
+ * \param extent The extent of the Quad_tree_impl.
+ * \param height The max height of the Quad_tree_impl.
+ * \param b_store_duplicates Put true to place elements deeper into the quad tree at intesecting quads, duplicates will be stored. Put false to only place elements into quads that can contain it.
+ */
+ QuadTreeImpl(Envelope2D extent, int height, boolean b_store_duplicates) {
+ m_quad_tree_nodes = (b_store_duplicates ? new StridedIndexTypeCollection(11) : new StridedIndexTypeCollection(10));
+ m_element_nodes = new StridedIndexTypeCollection(4);
+ m_data = new ArrayList(0);
+ m_free_data = new AttributeStreamOfInt32(0);
+ m_b_store_duplicates = b_store_duplicates;
+
+ m_extent = new Envelope2D();
+ m_data_extent = new Envelope2D();
+
+ reset_(extent, height);
+ }
+
+ /**
+ * Resets the Quad_tree_impl to the given extent and height.
+ * \param extent The extent of the Quad_tree_impl.
+ * \param height The max height of the Quad_tree_impl.
+ */
+ void reset(Envelope2D extent, int height) {
+ m_quad_tree_nodes.deleteAll(false);
+ m_element_nodes.deleteAll(false);
+ m_data.clear();
+ m_free_data.clear(false);
+ reset_(extent, height);
+ }
+
+ /**
+ * Inserts the element and bounding_box into the Quad_tree_impl.
+ * Note that this will invalidate any active iterator on the Quad_tree_impl.
+ * Returns an Element_handle corresponding to the element and bounding_box.
+ * \param element The element of the Geometry to be inserted.
+ * \param bounding_box The bounding_box of the Geometry to be inserted.
+ */
+ int insert(int element, Envelope2D bounding_box) {
+ if (m_root == -1)
+ create_root_();
+
+ if (m_b_store_duplicates) {
+ int success = insert_duplicates_(element, bounding_box, 0, m_extent, m_root, false, -1);
+
+ if (success != -1) {
+ if (m_data_extent.isEmpty())
+ m_data_extent.setCoords(bounding_box);
+ else
+ m_data_extent.merge(bounding_box);
+ }
+
+ return success;
+ }
+
+ int element_handle = insert_(element, bounding_box, 0, m_extent, m_root, false, -1);
+
+ if (element_handle != -1) {
+ if (m_data_extent.isEmpty())
+ m_data_extent.setCoords(bounding_box);
+ else
+ m_data_extent.merge(bounding_box);
+ }
+
+ return element_handle;
+ }
+
+ /**
+ * Inserts the element and bounding_box into the Quad_tree_impl at the given quad_handle.
+ * Note that this will invalidate any active iterator on the Quad_tree_impl.
+ * Returns an Element_handle corresponding to the element and bounding_box.
+ * \param element The element of the Geometry to be inserted.
+ * \param bounding_box The bounding_box of the Geometry to be inserted.
+ * \param hint_index A handle used as a hint where to place the element. This can be a handle obtained from a previous insertion and is useful on data having strong locality such as segments of a Polygon.
+ */
+ int insert(int element, Envelope2D bounding_box, int hint_index) {
+ if (m_root == -1)
+ create_root_();
+
+ if (m_b_store_duplicates) {
+ int success = insert_duplicates_(element, bounding_box, 0, m_extent, m_root, false, -1);
+
+ if (success != -1) {
+ if (m_data_extent.isEmpty())
+ m_data_extent.setCoords(bounding_box);
+ else
+ m_data_extent.merge(bounding_box);
+ }
+ return success;
+ }
+
+ int quad_handle;
+
+ if (hint_index == -1)
+ quad_handle = m_root;
+ else
+ quad_handle = get_quad_(hint_index);
+
+ int quad_height = getHeight(quad_handle);
+ Envelope2D quad_extent = getExtent(quad_handle);
+
+ int element_handle = insert_(element, bounding_box, quad_height, quad_extent, quad_handle, false, -1);
+
+ if (element_handle != -1) {
+ if (m_data_extent.isEmpty())
+ m_data_extent.setCoords(bounding_box);
+ else
+ m_data_extent.merge(bounding_box);
+ }
+
+ return element_handle;
+ }
+
+ /**
+ * Removes the element and bounding_box at the given element_handle.
+ * Note that this will invalidate any active iterator on the Quad_tree_impl.
+ * \param element_handle The handle corresponding to the element and bounding_box to be removed.
+ */
+ void removeElement(int element_handle) {
+ if (m_b_store_duplicates)
+ throw new GeometryException("invalid call");
+
+ int quad_handle = get_quad_(element_handle);
+ disconnect_element_handle_(element_handle);
+ free_element_and_box_node_(element_handle);
+
+ int q = quad_handle;
+
+ while (q != -1) {
+ set_sub_tree_element_count_(q, get_sub_tree_element_count_(q) - 1);
+ int parent = get_parent_(q);
+
+ if (get_sub_tree_element_count_(q) == 0) {
+ assert (get_local_element_count_(q) == 0);
+
+ if (q != m_root) {
+ int quadrant = get_quadrant_(q);
+ m_quad_tree_nodes.deleteElement(q);
+ set_child_(parent, quadrant, -1);
+ }
+ }
+
+ q = parent;
+ }
+ }
+
+ /**
+ * Returns the element at the given element_handle.
+ * \param element_handle The handle corresponding to the element to be retrieved.
+ */
+ int getElement(int element_handle) {
+ return get_element_value_(get_data_(element_handle));
+ }
+
+ /**
+ * Returns the ith unique element.
+ * \param i The index corresponding to the ith unique element.
+ */
+ int getElementAtIndex(int i) {
+ return m_data.get(i).element;
+ }
+
+ /**
+ * Returns the element extent at the given element_handle.
+ * \param element_handle The handle corresponding to the element extent to be retrieved.
+ */
+ Envelope2D getElementExtent(int element_handle) {
+ int data_handle = get_data_(element_handle);
+ return get_bounding_box_value_(data_handle);
+ }
+
+ /**
+ * Returns the extent of the ith unique element.
+ * \param i The index corresponding to the ith unique element.
+ */
+ Envelope2D getElementExtentAtIndex(int i) {
+ return m_data.get(i).box;
+ }
+
+ /**
+ * Returns the extent of all elements in the quad tree.
+ */
+ Envelope2D getDataExtent() {
+ return m_data_extent;
+ }
+
+ /**
+ * Returns the extent of the quad tree.
+ */
+ Envelope2D getQuadTreeExtent() {
+ return m_extent;
+ }
+
+ /**
+ * Returns the height of the quad at the given quad_handle.
+ * \param quad_handle The handle corresponding to the quad.
+ */
+ int getHeight(int quad_handle) {
+ return get_height_(quad_handle);
+ }
+
+ int getMaxHeight() {
+ return m_height;
+ }
+
+ /**
+ * Returns the extent of the quad at the given quad_handle.
+ * \param quad_handle The handle corresponding to the quad.
+ */
+ Envelope2D getExtent(int quad_handle) {
+ Envelope2D quad_extent = new Envelope2D();
+ quad_extent.setCoords(m_extent);
+
+ if (quad_handle == m_root)
+ return quad_extent;
+
+ AttributeStreamOfInt32 quadrants = new AttributeStreamOfInt32(0);
+
+ int q = quad_handle;
+
+ do {
+ quadrants.add(get_quadrant_(q));
+ q = get_parent_(q);
+
+ } while (q != m_root);
+
+ int sz = quadrants.size();
+ assert (sz == getHeight(quad_handle));
+
+ for (int i = 0; i < sz; i++) {
+ int child = quadrants.getLast();
+ quadrants.removeLast();
+
+ if (child == 0) {//northeast
+ quad_extent.xmin = 0.5 * (quad_extent.xmin + quad_extent.xmax);
+ quad_extent.ymin = 0.5 * (quad_extent.ymin + quad_extent.ymax);
+ } else if (child == 1) {//northwest
+ quad_extent.xmax = 0.5 * (quad_extent.xmin + quad_extent.xmax);
+ quad_extent.ymin = 0.5 * (quad_extent.ymin + quad_extent.ymax);
+ } else if (child == 2) {//southwest
+ quad_extent.xmax = 0.5 * (quad_extent.xmin + quad_extent.xmax);
+ quad_extent.ymax = 0.5 * (quad_extent.ymin + quad_extent.ymax);
+ } else {//southeast
+ quad_extent.xmin = 0.5 * (quad_extent.xmin + quad_extent.xmax);
+ quad_extent.ymax = 0.5 * (quad_extent.ymin + quad_extent.ymax);
+ }
+ }
+
+ return quad_extent;
+ }
+
+ /**
+ * Returns the Quad_handle of the quad containing the given element_handle.
+ * \param element_handle The handle corresponding to the element.
+ */
+ int getQuad(int element_handle) {
+ return get_quad_(element_handle);
+ }
+
+ /**
+ * Returns the number of elements in the Quad_tree_impl.
+ */
+ int getElementCount() {
+ if (m_root == -1)
+ return 0;
+
+ assert (get_sub_tree_element_count_(m_root) == m_data.size());
+ return get_sub_tree_element_count_(m_root);
+ }
+
+ /**
+ * Returns the number of elements in the subtree rooted at the given quad_handle.
+ * \param quad_handle The handle corresponding to the quad.
+ */
+ int getSubTreeElementCount(int quad_handle) {
+ return get_sub_tree_element_count_(quad_handle);
+ }
+
+ /**
+ * Returns the number of elements contained in the subtree rooted at the given quad_handle.
+ * \param quad_handle The handle corresponding to the quad.
+ */
+ int getContainedSubTreeElementCount(int quad_handle) {
+ if (!m_b_store_duplicates)
+ return get_sub_tree_element_count_(quad_handle);
+
+ return get_contained_sub_tree_element_count_(quad_handle);
+ }
+
+ /**
+ * Returns the number of elements in the quad tree that intersect the qiven query. Some elements may be duplicated if the quad tree stores duplicates.
+ * \param query The Envelope_2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ * \param max_count If the intersection count becomes greater than or equal to the max_count, then max_count is returned.
+ */
+ int getIntersectionCount(Envelope2D query, double tolerance, int max_count) {
+ if (m_root == -1)
+ return 0;
+
+ Envelope2D query_inflated = new Envelope2D();
+ query_inflated.setCoords(query);
+ query_inflated.inflate(tolerance, tolerance);
+
+ AttributeStreamOfInt32 quads_stack = new AttributeStreamOfInt32(0);
+ ArrayList extents_stack = new ArrayList(0);
+ quads_stack.add(m_root);
+ extents_stack.add(new Envelope2D(m_extent.xmin, m_extent.ymin, m_extent.xmax, m_extent.ymax));
+
+ Envelope2D[] child_extents = new Envelope2D[4];
+ child_extents[0] = new Envelope2D();
+ child_extents[1] = new Envelope2D();
+ child_extents[2] = new Envelope2D();
+ child_extents[3] = new Envelope2D();
+
+ Envelope2D current_extent = new Envelope2D();
+
+ int intersection_count = 0;
+
+ while (quads_stack.size() > 0) {
+ boolean b_subdivide = false;
+
+ int current_quad_handle = quads_stack.getLast();
+ current_extent.setCoords(extents_stack.get(extents_stack.size() - 1));
+
+ quads_stack.removeLast();
+ extents_stack.remove(extents_stack.size() - 1);
+
+
+ if (query_inflated.contains(current_extent)) {
+ intersection_count += getSubTreeElementCount(current_quad_handle);
+
+ if (max_count > 0 && intersection_count >= max_count)
+ return max_count;
+ } else {
+ if (query_inflated.isIntersecting(current_extent)) {
+ for (int element_handle = get_first_element_(current_quad_handle); element_handle != -1; element_handle = get_next_element_(element_handle)) {
+ int data_handle = get_data_(element_handle);
+ Envelope2D env = get_bounding_box_value_(data_handle);
+
+ if (env.isIntersecting(query_inflated)) {
+ intersection_count++;
+
+ if (max_count > 0 && intersection_count >= max_count)
+ return max_count;
+ }
+ }
+
+ b_subdivide = getHeight(current_quad_handle) + 1 <= m_height;
+ }
+ }
+
+ if (b_subdivide) {
+ set_child_extents_(current_extent, child_extents);
+
+ for (int i = 0; i < 4; i++) {
+ int child_handle = get_child_(current_quad_handle, i);
+
+ if (child_handle != -1 && getSubTreeElementCount(child_handle) > 0) {
+ boolean b_is_intersecting = query_inflated.isIntersecting(child_extents[i]);
+
+ if (b_is_intersecting) {
+ quads_stack.add(child_handle);
+ extents_stack.add(new Envelope2D(child_extents[i].xmin, child_extents[i].ymin, child_extents[i].xmax, child_extents[i].ymax));
+ }
+ }
+ }
+ }
+ }
+
+ return intersection_count;
+ }
+
+ /**
+ * Returns true if the quad tree has data intersecting the given query.
+ * \param query The Envelope_2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ boolean hasData(Envelope2D query, double tolerance) {
+ int count = getIntersectionCount(query, tolerance, 1);
+ return count >= 1;
+ }
+
+ /**
+ * Gets an iterator on the Quad_tree_impl. The query will be the Envelope_2D
+ * that bounds the input Geometry. To reuse the existing iterator on the
+ * same Quad_tree_impl but with a new query, use the reset_iterator function
+ * on the Quad_tree_iterator_impl. \param query The Geometry used for the
+ * query. If the Geometry is a Line segment, then the query will be the
+ * segment. Otherwise the query will be the Envelope_2D bounding the
+ * Geometry. \param tolerance The tolerance used for the intersection tests.
+ */
+ QuadTreeIteratorImpl getIterator(Geometry query, double tolerance) {
+ return new QuadTreeIteratorImpl(this, query, tolerance);
+ }
+
+ /**
+ * Gets an iterator on the Quad_tree_impl using the input Envelope_2D as the
+ * query. To reuse the existing iterator on the same Quad_tree_impl but with
+ * a new query, use the reset_iterator function on the
+ * Quad_tree_iterator_impl. \param query The Envelope_2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ QuadTreeIteratorImpl getIterator(Envelope2D query, double tolerance) {
+ return new QuadTreeIteratorImpl(this, query, tolerance);
+ }
+
+ /**
+ * Gets an iterator on the Quad_tree.
+ */
+ QuadTreeIteratorImpl getIterator() {
+ return new QuadTreeIteratorImpl(this);
+ }
+
+ /**
+ * Gets a sorted iterator on the Quad_tree_impl. The Element_handles will be returned in increasing order of their corresponding Element_types.
+ * The query will be the Envelope_2D that bounds the input Geometry.
+ * To reuse the existing iterator on the same Quad_tree_impl but with a new query, use the reset_iterator function on the Quad_tree_sorted_iterator_impl.
+ * \param query The Geometry used for the query. If the Geometry is a Line segment, then the query will be the segment. Otherwise the query will be the Envelope_2D bounding the Geometry.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ QuadTreeSortedIteratorImpl getSortedIterator(Geometry query, double tolerance) {
+ return new QuadTreeSortedIteratorImpl(getIterator(query, tolerance));
+ }
+
+ /**
+ * Gets a sorted iterator on the Quad_tree_impl using the input Envelope_2D as the query. The Element_handles will be returned in increasing order of their corresponding Element_types.
+ * To reuse the existing iterator on the same Quad_tree_impl but with a new query, use the reset_iterator function on the Quad_tree_iterator_impl.
+ * \param query The Envelope_2D used for the query.
+ * \param tolerance The tolerance used for the intersection tests.
+ */
+ QuadTreeSortedIteratorImpl getSortedIterator(Envelope2D query, double tolerance) {
+ return new QuadTreeSortedIteratorImpl(getIterator(query, tolerance));
+ }
+
+ /**
+ * Gets a sorted iterator on the Quad_tree. The Element_handles will be returned in increasing order of their corresponding Element_types
+ */
+ QuadTreeSortedIteratorImpl getSortedIterator() {
+ return new QuadTreeSortedIteratorImpl(getIterator());
+ }
+
+ public long estimateMemorySize()
+ {
+ long size = SIZE_OF_QUAD_TREE_IMPL +
+ (m_extent != null ? m_extent.estimateMemorySize() : 0) +
+ (m_data_extent != null ? m_data_extent.estimateMemorySize() : 0) +
+ (m_quad_tree_nodes != null ? m_quad_tree_nodes.estimateMemorySize() : 0) +
+ (m_element_nodes != null ? m_element_nodes.estimateMemorySize() : 0) +
+ (m_free_data != null ? m_free_data.estimateMemorySize() : 0);
+
+ if (m_data != null) {
+ size += sizeOfObjectArray(m_data.size()) + m_data.size() * SIZE_OF_DATA;
+ }
+
+ return size;
+ }
+
+ private void reset_(Envelope2D extent, int height) {
+ if (height < 0 || height > 127)
+ throw new IllegalArgumentException("invalid height");
+
+ m_height = height;
+ m_extent.setCoords(extent);
+ m_root = m_quad_tree_nodes.newElement();
+ m_data_extent.setEmpty();
+ m_root = -1;
+ }
+
+ private int insert_(int element, Envelope2D bounding_box, int height, Envelope2D quad_extent, int quad_handle, boolean b_flushing, int flushed_element_handle) {
+ if (!quad_extent.contains(bounding_box)) {
+ assert (!b_flushing);
+
+ if (height == 0)
+ return -1;
+
+ return insert_(element, bounding_box, 0, m_extent, m_root, b_flushing, flushed_element_handle);
+ }
+
+ if (!b_flushing) {
+ for (int q = quad_handle; q != -1; q = get_parent_(q))
+ set_sub_tree_element_count_(q, get_sub_tree_element_count_(q) + 1);
+ }
+
+ Envelope2D current_extent = new Envelope2D();
+ current_extent.setCoords(quad_extent);
+
+ int current_quad_handle = quad_handle;
+
+ Envelope2D[] child_extents = new Envelope2D[4];
+ child_extents[0] = new Envelope2D();
+ child_extents[1] = new Envelope2D();
+ child_extents[2] = new Envelope2D();
+ child_extents[3] = new Envelope2D();
+
+ int current_height;
+ for (current_height = height; current_height < m_height && can_push_down_(current_quad_handle); current_height++) {
+ set_child_extents_(current_extent, child_extents);
+
+ boolean b_contains = false;
+
+ for (int i = 0; i < 4; i++) {
+ if (child_extents[i].contains(bounding_box)) {
+ b_contains = true;
+
+ int child_handle = get_child_(current_quad_handle, i);
+ if (child_handle == -1)
+ child_handle = create_child_(current_quad_handle, i);
+
+ set_sub_tree_element_count_(child_handle, get_sub_tree_element_count_(child_handle) + 1);
+
+ current_quad_handle = child_handle;
+ current_extent.setCoords(child_extents[i]);
+ break;
+ }
+ }
+
+ if (!b_contains)
+ break;
+ }
+
+ return insert_at_quad_(element, bounding_box, current_height, current_extent, current_quad_handle, b_flushing, quad_handle, flushed_element_handle, -1);
+ }
+
+ private int insert_duplicates_(int element, Envelope2D bounding_box, int height, Envelope2D quad_extent, int quad_handle, boolean b_flushing, int flushed_element_handle) {
+ assert (b_flushing || m_root == quad_handle);
+
+ if (!b_flushing) // If b_flushing is true, then the sub tree element counts are already accounted for since the element already lies in the current incoming quad
+ {
+ if (!quad_extent.contains(bounding_box))
+ return -1;
+
+ set_sub_tree_element_count_(quad_handle, get_sub_tree_element_count_(quad_handle) + 1);
+ set_contained_sub_tree_element_count_(quad_handle, get_contained_sub_tree_element_count_(quad_handle) + 1);
+ }
+
+ double bounding_box_max_dim = Math.max(bounding_box.getWidth(), bounding_box.getHeight());
+
+ int element_handle = -1;
+ AttributeStreamOfInt32 quads_stack = new AttributeStreamOfInt32(0);
+ ArrayList extents_stack = new ArrayList(0);
+ AttributeStreamOfInt32 heights_stack = new AttributeStreamOfInt32(0);
+ quads_stack.add(quad_handle);
+ extents_stack.add(new Envelope2D(quad_extent.xmin, quad_extent.ymin, quad_extent.xmax, quad_extent.ymax));
+ heights_stack.add(height);
+
+ Envelope2D[] child_extents = new Envelope2D[4];
+ child_extents[0] = new Envelope2D();
+ child_extents[1] = new Envelope2D();
+ child_extents[2] = new Envelope2D();
+ child_extents[3] = new Envelope2D();
+
+ Envelope2D current_extent = new Envelope2D();
+
+ while (quads_stack.size() > 0) {
+ boolean b_subdivide = false;
+
+ int current_quad_handle = quads_stack.getLast();
+ current_extent.setCoords(extents_stack.get(extents_stack.size() - 1));
+ int current_height = heights_stack.getLast();
+
+ quads_stack.removeLast();
+ extents_stack.remove(extents_stack.size() - 1);
+ heights_stack.removeLast();
+
+ if (current_height + 1 < m_height && can_push_down_(current_quad_handle)) {
+ double current_extent_max_dim = Math.max(current_extent.getWidth(), current_extent.getHeight());
+
+ if (bounding_box_max_dim <= current_extent_max_dim / 2.0)
+ b_subdivide = true;
+ }
+
+ if (b_subdivide) {
+ set_child_extents_(current_extent, child_extents);
+
+ boolean b_contains = false;
+
+ for (int i = 0; i < 4; i++) {
+ b_contains = child_extents[i].contains(bounding_box);
+
+ if (b_contains) {
+ int child_handle = get_child_(current_quad_handle, i);
+ if (child_handle == -1)
+ child_handle = create_child_(current_quad_handle, i);
+
+ quads_stack.add(child_handle);
+ extents_stack.add(new Envelope2D(child_extents[i].xmin, child_extents[i].ymin, child_extents[i].xmax, child_extents[i].ymax));
+ heights_stack.add(current_height + 1);
+
+ set_sub_tree_element_count_(child_handle, get_sub_tree_element_count_(child_handle) + 1);
+ set_contained_sub_tree_element_count_(child_handle, get_contained_sub_tree_element_count_(child_handle) + 1);
+ break;
+ }
+ }
+
+ if (!b_contains) {
+ for (int i = 0; i < 4; i++) {
+ boolean b_intersects = child_extents[i].isIntersecting(bounding_box);
+
+ if (b_intersects) {
+ int child_handle = get_child_(current_quad_handle, i);
+ if (child_handle == -1)
+ child_handle = create_child_(current_quad_handle, i);
+
+ quads_stack.add(child_handle);
+ extents_stack.add(new Envelope2D(child_extents[i].xmin, child_extents[i].ymin, child_extents[i].xmax, child_extents[i].ymax));
+ heights_stack.add(current_height + 1);
+
+ set_sub_tree_element_count_(child_handle, get_sub_tree_element_count_(child_handle) + 1);
+ }
+ }
+ }
+ } else {
+ element_handle = insert_at_quad_(element, bounding_box, current_height, current_extent, current_quad_handle, b_flushing, quad_handle, flushed_element_handle, element_handle);
+ b_flushing = false; // flushing is false after the first inserted element has been flushed down, all subsequent inserts will be new
+ }
+ }
+
+ return 0;
+ }
+
+ private int insert_at_quad_(int element, Envelope2D bounding_box, int current_height, Envelope2D current_extent, int current_quad_handle, boolean b_flushing, int quad_handle, int flushed_element_handle, int duplicate_element_handle) {
+ // If the bounding box is not contained in any of the current_node's children, or if the current_height is m_height, then insert the element and
+ // bounding box into the current_node
+
+ int head_element_handle = get_first_element_(current_quad_handle);
+ int tail_element_handle = get_last_element_(current_quad_handle);
+ int element_handle = -1;
+
+ if (b_flushing) {
+ assert (flushed_element_handle != -1);
+
+ if (current_quad_handle == quad_handle)
+ return flushed_element_handle;
+
+ disconnect_element_handle_(flushed_element_handle); // Take it out of the incoming quad_handle, and place in current_quad_handle
+ element_handle = flushed_element_handle;
+ } else {
+ if (duplicate_element_handle == -1) {
+ element_handle = create_element_();
+ set_data_values_(get_data_(element_handle), element, bounding_box);
+ } else {
+ assert (m_b_store_duplicates);
+ element_handle = create_element_from_duplicate_(duplicate_element_handle);
+ }
+ }
+
+ assert (!b_flushing || element_handle == flushed_element_handle);
+
+ set_quad_(element_handle, current_quad_handle); // set parent quad (needed for removal of element)
+
+ // assign the prev pointer of the new tail to point at the old tail (tail_element_handle)
+ // assign the next pointer of the old tail to point at the new tail (next_element_handle)
+ if (tail_element_handle != -1) {
+ set_prev_element_(element_handle, tail_element_handle);
+ set_next_element_(tail_element_handle, element_handle);
+ } else {
+ assert (head_element_handle == -1);
+ set_first_element_(current_quad_handle, element_handle);
+ }
+
+ // assign the new tail
+ set_last_element_(current_quad_handle, element_handle);
+
+ set_local_element_count_(current_quad_handle, get_local_element_count_(current_quad_handle) + 1);
+
+ if (can_flush_(current_quad_handle))
+ flush_(current_height, current_extent, current_quad_handle);
+
+ return element_handle;
+ }
+
+ private static void set_child_extents_(Envelope2D current_extent, Envelope2D[] child_extents) {
+ double x_mid = 0.5 * (current_extent.xmin + current_extent.xmax);
+ double y_mid = 0.5 * (current_extent.ymin + current_extent.ymax);
+
+ child_extents[0].setCoords(x_mid, y_mid, current_extent.xmax, current_extent.ymax); // northeast
+ child_extents[1].setCoords(current_extent.xmin, y_mid, x_mid, current_extent.ymax); // northwest
+ child_extents[2].setCoords(current_extent.xmin, current_extent.ymin, x_mid, y_mid); // southwest
+ child_extents[3].setCoords(x_mid, current_extent.ymin, current_extent.xmax, y_mid); // southeast
+ }
+
+ private void disconnect_element_handle_(int element_handle) {
+ assert (element_handle != -1);
+ int quad_handle = get_quad_(element_handle);
+ int head_element_handle = get_first_element_(quad_handle);
+ int tail_element_handle = get_last_element_(quad_handle);
+ int prev_element_handle = get_prev_element_(element_handle);
+ int next_element_handle = get_next_element_(element_handle);
+ assert (head_element_handle != -1 && tail_element_handle != -1);
+
+ if (head_element_handle == element_handle) {
+ if (next_element_handle != -1)
+ set_prev_element_(next_element_handle, -1);
+ else {
+ assert (head_element_handle == tail_element_handle);
+ assert (get_local_element_count_(quad_handle) == 1);
+ set_last_element_(quad_handle, -1);
+ }
+
+ set_first_element_(quad_handle, next_element_handle);
+ } else if (tail_element_handle == element_handle) {
+ assert (prev_element_handle != -1);
+ assert (get_local_element_count_(quad_handle) >= 2);
+ set_next_element_(prev_element_handle, -1);
+ set_last_element_(quad_handle, prev_element_handle);
+ } else {
+ assert (next_element_handle != -1 && prev_element_handle != -1);
+ assert (get_local_element_count_(quad_handle) >= 3);
+ set_prev_element_(next_element_handle, prev_element_handle);
+ set_next_element_(prev_element_handle, next_element_handle);
+ }
+
+ set_prev_element_(element_handle, -1);
+ set_next_element_(element_handle, -1);
+
+ set_local_element_count_(quad_handle, get_local_element_count_(quad_handle) - 1);
+ assert (get_local_element_count_(quad_handle) >= 0);
+ }
+
+ private boolean can_flush_(int quad_handle) {
+ return get_local_element_count_(quad_handle) == m_flushing_count && !has_children_(quad_handle);
+ }
+
+ private void flush_(int height, Envelope2D extent, int quad_handle) {
+ int element;
+ Envelope2D bounding_box = new Envelope2D();
+
+ assert (quad_handle != -1);
+
+ int element_handle = get_first_element_(quad_handle), next_handle = -1;
+ int data_handle = -1;
+ assert (element_handle != -1);
+
+ do {
+ data_handle = get_data_(element_handle);
+ element = get_element_value_(data_handle);
+ bounding_box.setCoords(get_bounding_box_value_(data_handle));
+
+ next_handle = get_next_element_(element_handle);
+
+ if (!m_b_store_duplicates)
+ insert_(element, bounding_box, height, extent, quad_handle, true, element_handle);
+ else
+ insert_duplicates_(element, bounding_box, height, extent, quad_handle, true, element_handle);
+
+ element_handle = next_handle;
+
+ } while (element_handle != -1);
+ }
+
+ private boolean can_push_down_(int quad_handle) {
+ return get_local_element_count_(quad_handle) >= m_flushing_count || has_children_(quad_handle);
+ }
+
+ private boolean has_children_(int parent) {
+ return get_child_(parent, 0) != -1 || get_child_(parent, 1) != -1 || get_child_(parent, 2) != -1 || get_child_(parent, 3) != -1;
+ }
+
+ private int create_child_(int parent, int quadrant) {
+ int child = m_quad_tree_nodes.newElement();
+ set_child_(parent, quadrant, child);
+ set_sub_tree_element_count_(child, 0);
+ set_local_element_count_(child, 0);
+ set_parent_(child, parent);
+ set_height_and_quadrant_(child, get_height_(parent) + 1, quadrant);
+
+ if (m_b_store_duplicates)
+ set_contained_sub_tree_element_count_(child, 0);
+
+ return child;
+ }
+
+ private void create_root_() {
+ m_root = m_quad_tree_nodes.newElement();
+ set_sub_tree_element_count_(m_root, 0);
+ set_local_element_count_(m_root, 0);
+ set_height_and_quadrant_(m_root, 0, 0);
+
+ if (m_b_store_duplicates)
+ set_contained_sub_tree_element_count_(m_root, 0);
+ }
+
+ private int create_element_() {
+ int element_handle = m_element_nodes.newElement();
+ int data_handle;
+
+ if (m_free_data.size() > 0) {
+ data_handle = m_free_data.get(m_free_data.size() - 1);
+ m_free_data.removeLast();
+ } else {
+ data_handle = m_data.size();
+ m_data.add(null);
+ }
+
+ set_data_(element_handle, data_handle);
+ return element_handle;
+ }
+
+ private int create_element_from_duplicate_(int duplicate_element_handle) {
+ int element_handle = m_element_nodes.newElement();
+ int data_handle = get_data_(duplicate_element_handle);
+ set_data_(element_handle, data_handle);
+ return element_handle;
+ }
+
+ private void free_element_and_box_node_(int element_handle) {
+ int data_handle = get_data_(element_handle);
+ m_free_data.add(data_handle);
+ m_element_nodes.deleteElement(element_handle);
+ }
+
+ private int get_child_(int quad_handle, int quadrant) {
+ return m_quad_tree_nodes.getField(quad_handle, quadrant);
+ }
+
+ private void set_child_(int parent, int quadrant, int child) {
+ m_quad_tree_nodes.setField(parent, quadrant, child);
+ }
+
+ private int get_first_element_(int quad_handle) {
+ return m_quad_tree_nodes.getField(quad_handle, 4);
+ }
+
+ private void set_first_element_(int quad_handle, int head) {
+ m_quad_tree_nodes.setField(quad_handle, 4, head);
+ }
+
+ private int get_last_element_(int quad_handle) {
+ return m_quad_tree_nodes.getField(quad_handle, 5);
+ }
+
+ private void set_last_element_(int quad_handle, int tail) {
+ m_quad_tree_nodes.setField(quad_handle, 5, tail);
+ }
+
+
+ private int get_quadrant_(int quad_handle) {
+ int height_quadrant_hybrid = m_quad_tree_nodes.getField(quad_handle, 6);
+ int quadrant = height_quadrant_hybrid & m_quadrant_mask;
+ return quadrant;
+ }
+
+ private int get_height_(int quad_handle) {
+ int height_quadrant_hybrid = m_quad_tree_nodes.getField(quad_handle, 6);
+ int height = height_quadrant_hybrid >> m_height_bit_shift;
+ return height;
+ }
+
+ private void set_height_and_quadrant_(int quad_handle, int height, int quadrant) {
+ assert (quadrant >= 0 && quadrant <= 3);
+ int height_quadrant_hybrid = (int) ((height << m_height_bit_shift) | quadrant);
+ m_quad_tree_nodes.setField(quad_handle, 6, height_quadrant_hybrid);
+ }
+
+ private int get_local_element_count_(int quad_handle) {
+ return m_quad_tree_nodes.getField(quad_handle, 7);
+ }
+
+ private void set_local_element_count_(int quad_handle, int count) {
+ m_quad_tree_nodes.setField(quad_handle, 7, count);
+ }
+
+ private int get_sub_tree_element_count_(int quad_handle) {
+ return m_quad_tree_nodes.getField(quad_handle, 8);
+ }
+
+ private void set_sub_tree_element_count_(int quad_handle, int count) {
+ m_quad_tree_nodes.setField(quad_handle, 8, count);
+ }
+
+ private int get_parent_(int child) {
+ return m_quad_tree_nodes.getField(child, 9);
+ }
+
+ private void set_parent_(int child, int parent) {
+ m_quad_tree_nodes.setField(child, 9, parent);
+ }
+
+ private int get_contained_sub_tree_element_count_(int quad_handle) {
+ return m_quad_tree_nodes.getField(quad_handle, 10);
+ }
+
+ private void set_contained_sub_tree_element_count_(int quad_handle, int count) {
+ m_quad_tree_nodes.setField(quad_handle, 10, count);
+ }
+
+ private int get_data_(int element_handle) {
+ return m_element_nodes.getField(element_handle, 0);
+ }
+
+ private void set_data_(int element_handle, int data_handle) {
+ m_element_nodes.setField(element_handle, 0, data_handle);
+ }
+
+ private int get_prev_element_(int element_handle) {
+ return m_element_nodes.getField(element_handle, 1);
+ }
+
+ private int get_next_element_(int element_handle) {
+ return m_element_nodes.getField(element_handle, 2);
+ }
+
+ private void set_prev_element_(int element_handle, int prev_handle) {
+ m_element_nodes.setField(element_handle, 1, prev_handle);
+ }
+
+ private void set_next_element_(int element_handle, int next_handle) {
+ m_element_nodes.setField(element_handle, 2, next_handle);
+ }
+
+ private int get_quad_(int element_handle) {
+ return m_element_nodes.getField(element_handle, 3);
+ }
+
+ private void set_quad_(int element_handle, int parent) {
+ m_element_nodes.setField(element_handle, 3, parent);
+ }
+
+ private int get_element_value_(int data_handle) {
+ return m_data.get(data_handle).element;
+ }
+
+ private Envelope2D get_bounding_box_value_(int data_handle) {
+ return m_data.get(data_handle).box;
+ }
+
+ private void set_data_values_(int data_handle, int element, Envelope2D bounding_box) {
+ m_data.set(data_handle, new Data(element, bounding_box));
+ }
+
+ private Envelope2D m_extent;
+ private Envelope2D m_data_extent;
+ private StridedIndexTypeCollection m_quad_tree_nodes;
+ private StridedIndexTypeCollection m_element_nodes;
+ transient private ArrayList m_data;
+ private AttributeStreamOfInt32 m_free_data;
+ private int m_root;
+ private int m_height;
+ private boolean m_b_store_duplicates;
+
+ final static private int m_quadrant_mask = 3;
+ final static private int m_height_bit_shift = 2;
+ final static private int m_flushing_count = 5;
+
+ static final class Data {
+ int element;
+ Envelope2D box;
+
+ Data(int element_, double x1, double y1, double x2, double y2) {
+ element = element_;
+ box = new Envelope2D();
+ box.setCoords(x1, y1, x2, y2);
+ }
+
+ Data(int element_, Envelope2D box_) {
+ element = element_;
+ box = new Envelope2D();
+ box.setCoords(box_);
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream stream)
+ throws IOException {
+ stream.defaultWriteObject();
+ stream.writeInt(m_data.size());
+ for (int i = 0, n = m_data.size(); i < n; ++i) {
+ Data d = m_data.get(i);
+ if (d != null) {
+ stream.writeByte(1);
+ stream.writeInt(d.element);
+ stream.writeDouble(d.box.xmin);
+ stream.writeDouble(d.box.ymin);
+ stream.writeDouble(d.box.xmax);
+ stream.writeDouble(d.box.ymax);
+ }
+ else {
+ stream.writeByte(0);
+ }
+
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ int dataSize = stream.readInt();
+ m_data = new ArrayList(dataSize);
+ for (int i = 0, n = dataSize; i < n; ++i) {
+ int b = stream.readByte();
+ if (b == 1) {
+ int elm = stream.readInt();
+ double x1 = stream.readDouble();
+ double y1 = stream.readDouble();
+ double x2 = stream.readDouble();
+ double y2 = stream.readDouble();
+ Data d = new Data(elm, x1, y1, x2, y2);
+ m_data.add(d);
+ }
+ else if (b == 0) {
+ m_data.add(null);
+ }
+ else {
+ throw new IOException();
+ }
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private void readObjectNoData() throws ObjectStreamException {
+ throw new InvalidObjectException("Stream data required");
+ }
+
+ /* m_quad_tree_nodes
+ * 0: m_north_east_child
+ * 1: m_north_west_child
+ * 2: m_south_west_child
+ * 3: m_south_east_child
+ * 4: m_head_element
+ * 5: m_tail_element
+ * 6: m_quadrant_and_height
+ * 7: m_local_element_count
+ * 8: m_sub_tree_element_count
+ * 9: m_parent_quad
+ * 10: m_height
+ */
+
+ /* m_element_nodes
+ * 0: m_data_handle
+ * 1: m_prev
+ * 2: m_next
+ * 3: m_parent_quad
+ */
+
+ /* m_data
+ * element
+ * box
+ */
+}
diff --git a/src/com/esri/core/geometry/RasterizedGeometry2D.java b/src/main/java/com/esri/core/geometry/RasterizedGeometry2D.java
similarity index 81%
rename from src/com/esri/core/geometry/RasterizedGeometry2D.java
rename to src/main/java/com/esri/core/geometry/RasterizedGeometry2D.java
index 54ca904b..ff1b8257 100644
--- a/src/com/esri/core/geometry/RasterizedGeometry2D.java
+++ b/src/main/java/com/esri/core/geometry/RasterizedGeometry2D.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
-abstract class RasterizedGeometry2D {
+public abstract class RasterizedGeometry2D {
public enum HitType {
Outside(0), // the test geometry is well outside the geometry bounds
@@ -33,7 +33,7 @@ public enum HitType {
Border(2); // the test geometry is close to the bounds or intersects the
// bounds
- private int enumVal;
+ int enumVal;
private HitType(int val) {
enumVal = val;
@@ -41,7 +41,7 @@ private HitType(int val) {
}
/**
- * Test a point agains the RasterizedGeometry
+ * Test a point against the RasterizedGeometry
*/
public abstract HitType queryPointInGeometry(double x, double y);
@@ -54,11 +54,11 @@ private HitType(int val) {
* Creates a rasterized geometry from a given Geometry.
*
* @param geom
- * The input geometry to rasterize.
+ * The input geometry to rasterize. It has to be a MultiVertexGeometry instance.
* @param toleranceXY
* The tolerance of the rasterization. Raster pixels that are
* closer than given tolerance to the Geometry will be set.
- * @param rasterSize
+ * @param rasterSizeBytes
* The max size of the raster in bytes. The raster has size of
* rasterSize x rasterSize. Polygons are rasterized into 2 bpp
* (bits per pixel) rasters while other geometries are rasterized
@@ -75,7 +75,7 @@ public static RasterizedGeometry2D create(Geometry geom,
return (RasterizedGeometry2D) gc;
}
- public static RasterizedGeometry2D create(MultiVertexGeometryImpl geom,
+ static RasterizedGeometry2D create(MultiVertexGeometryImpl geom,
double toleranceXY, int rasterSizeBytes) {
if (!canUseAccelerator(geom))
throw new IllegalArgumentException();
@@ -100,7 +100,7 @@ public static int rasterSizeFromAccelerationDegree(
value = 1024 * 1024 * 2 / 8;// 256k
break;
default:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
return value;
@@ -121,19 +121,25 @@ static boolean canUseAccelerator(Geometry geom) {
/**
* Returns the tolerance for which the rasterized Geometry has been built.
*/
- abstract double getToleranceXY();
+ public abstract double getToleranceXY();
/**
* Returns raster size in bytes
*/
- abstract int getRasterSize();
+ public abstract int getRasterSize();
/**
- * Dumps the raster to file for debug purposes.
+ * Dumps the raster to a bmp file for debug purposes.
*
* @param fileName
- * @returns true if success, false otherwise.
+ * @return true if success, false otherwise.
*/
- abstract boolean dbgSaveToBitmap(String fileName);
+ public abstract boolean dbgSaveToBitmap(String fileName);
+ /**
+ * Returns an estimate of this object size in bytes.
+ *
+ * @return Returns an estimate of this object size in bytes.
+ */
+ public abstract long estimateMemorySize();
}
diff --git a/src/main/java/com/esri/core/geometry/RasterizedGeometry2DImpl.java b/src/main/java/com/esri/core/geometry/RasterizedGeometry2DImpl.java
new file mode 100644
index 00000000..c7def2d4
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/RasterizedGeometry2DImpl.java
@@ -0,0 +1,581 @@
+/*
+ Copyright 1995-2013 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_RASTERIZED_GEOMETRY_2D_IMPL;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_SCAN_CALLBACK_IMPL;
+import static com.esri.core.geometry.SizeOf.sizeOfIntArray;
+
+final class RasterizedGeometry2DImpl extends RasterizedGeometry2D {
+ int[] m_bitmap;
+ int m_scanLineSize;
+ int m_width;
+ double m_dx;
+ double m_dy;
+ double m_x0;
+ double m_y0;
+ double m_toleranceXY;
+ double m_stroke_half_widthX_pix;
+ double m_stroke_half_widthY_pix;
+ double m_stroke_half_width;
+
+ Envelope2D m_geomEnv;// envelope of the raster in world coordinates
+ Transformation2D m_transform;
+ int m_dbgTestCount;
+ SimpleRasterizer m_rasterizer;
+ ScanCallbackImpl m_callback;
+
+ class ScanCallbackImpl implements SimpleRasterizer.ScanCallback {
+ int[] m_bitmap;
+ int m_scanlineWidth;
+ int m_color;
+
+ public ScanCallbackImpl(int[] bitmap, int scanlineWidth) {
+ m_scanlineWidth = scanlineWidth;
+ m_bitmap = bitmap;
+ }
+
+ public void setColor(SimpleRasterizer rasterizer, int color) {
+ if (m_color != color)
+ rasterizer.flush();
+
+ m_color = color;// set new color
+ }
+
+ @Override
+ public void drawScan(int[] scans, int scanCount3) {
+ for (int i = 0; i < scanCount3; ) {
+ int x0 = scans[i++];
+ int x1 = scans[i++];
+ int y = scans[i++];
+
+ int scanlineStart = y * m_scanlineWidth;
+ for (int xx = x0; xx < x1; xx++) {
+ m_bitmap[scanlineStart + (xx >> 4)] |= m_color << ((xx & 15) * 2);// 2
+ // bit
+ // per
+ // color
+ }
+ }
+ }
+
+ /**
+ * Returns an estimate of this object size in bytes.
+ *
+ * @return Returns an estimate of this object size in bytes.
+ */
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_SCAN_CALLBACK_IMPL +
+ (m_bitmap != null ? sizeOfIntArray(m_bitmap.length) : 0);
+ }
+ }
+
+ void fillMultiPath(SimpleRasterizer rasterizer, Transformation2D trans, MultiPathImpl polygon, boolean isWinding) {
+ SegmentIteratorImpl segIter = polygon.querySegmentIterator();
+ Point2D p1 = new Point2D();
+ Point2D p2 = new Point2D();
+ while (segIter.nextPath()) {
+ while (segIter.hasNextSegment()) {
+ Segment seg = segIter.nextSegment();
+ if (seg.getType() != Geometry.Type.Line)
+ throw GeometryException.GeometryInternalError(); // TODO:
+ // densify
+ // the
+ // segment
+ // here
+ trans.transform(seg.getStartXY(), p1);
+ trans.transform(seg.getEndXY(), p2);
+ m_rasterizer.addEdge(p1.x, p1.y, p2.x, p2.y);
+ }
+ }
+
+ m_rasterizer.renderEdges(isWinding ? SimpleRasterizer.WINDING : SimpleRasterizer.EVEN_ODD);
+ }
+
+ void fillPoints(SimpleRasterizer rasterizer, MultiPointImpl geom, double stroke_half_width) {
+ throw GeometryException.GeometryInternalError();
+ }
+
+ void fillConvexPolygon(SimpleRasterizer rasterizer, Point2D[] fan, int len) {
+ for (int i = 1, n = len; i < n; i++) {
+ rasterizer.addEdge(fan[i-1].x, fan[i-1].y, fan[i].x, fan[i].y);
+ }
+ rasterizer.addEdge(fan[len-1].x, fan[len-1].y, fan[0].x, fan[0].y);
+ m_rasterizer.renderEdges(SimpleRasterizer.EVEN_ODD);
+ }
+
+ void fillEnvelope(SimpleRasterizer rasterizer, Envelope2D envIn) {
+ rasterizer.fillEnvelope(envIn);
+ }
+
+ void strokeDrawPolyPath(SimpleRasterizer rasterizer,
+ MultiPathImpl polyPath, double tol) {
+
+ Point2D[] fan = new Point2D[4];
+ for (int i = 0; i < fan.length; i++)
+ fan[i] = new Point2D();
+
+ SegmentIteratorImpl segIter = polyPath.querySegmentIterator();
+ double strokeHalfWidth = m_transform.transform(tol) + 1.5;
+
+ Point2D ptStart = new Point2D();
+ Point2D ptEnd = new Point2D();
+ Point2D prev_start = new Point2D();
+ Point2D prev_end = new Point2D();
+ double[] helper_xy_10_elm = new double[10];
+ Envelope2D segEnv = new Envelope2D();
+ Point2D ptOld = new Point2D();
+ double extraWidth = 0;
+ while (segIter.nextPath()) {
+ boolean hasFan = false;
+ boolean first = true;
+ ptOld.setCoords(0, 0);
+ while (segIter.hasNextSegment()) {
+ Segment seg = segIter.nextSegment();
+ ptStart.x = seg.getStartX();
+ ptStart.y = seg.getStartY();
+ ptEnd.x = seg.getEndX();
+ ptEnd.y = seg.getEndY();
+ segEnv.setEmpty();
+ segEnv.merge(ptStart.x, ptStart.y);
+ segEnv.mergeNE(ptEnd.x, ptEnd.y);
+ if (!m_geomEnv.isIntersectingNE(segEnv)) {
+ if (hasFan) {
+ rasterizer.startAddingEdges();
+ rasterizer.addSegmentStroke(prev_start.x, prev_start.y,
+ prev_end.x, prev_end.y, strokeHalfWidth + extraWidth, false,
+ helper_xy_10_elm);
+ rasterizer.renderEdges(SimpleRasterizer.EVEN_ODD);
+ hasFan = false;
+ extraWidth = 0.0;
+ }
+
+ first = true;
+ continue;
+ }
+
+ m_transform.transform(ptEnd, ptEnd);
+
+ if (first) {
+ m_transform.transform(ptStart, ptStart);
+ ptOld.setCoords(ptStart);
+ first = false;
+ } else {
+ ptStart.setCoords(ptOld);
+ }
+
+ prev_start.setCoords(ptStart);
+ prev_end.setCoords(ptEnd);
+
+ rasterizer.startAddingEdges();
+ hasFan = !rasterizer.addSegmentStroke(prev_start.x,
+ prev_start.y, prev_end.x, prev_end.y, strokeHalfWidth + extraWidth,
+ true, helper_xy_10_elm);
+ rasterizer.renderEdges(SimpleRasterizer.EVEN_ODD);
+ if (!hasFan) {
+ ptOld.setCoords(prev_end);
+ extraWidth = 0.0;
+ }
+ else {
+ //track length of skipped segment to add it to the stroke width for the next edge.
+ extraWidth = Math.max(extraWidth, Point2D.distance(prev_start, prev_end));
+ }
+ }
+
+ if (hasFan) {
+ rasterizer.startAddingEdges();
+ hasFan = !rasterizer.addSegmentStroke(prev_start.x,
+ prev_start.y, prev_end.x, prev_end.y, strokeHalfWidth + extraWidth,
+ false, helper_xy_10_elm);
+ rasterizer.renderEdges(SimpleRasterizer.EVEN_ODD);
+ extraWidth = 0.0;
+ }
+ }
+ }
+
+ int worldToPixX(double x) {
+ return (int) (x * m_dx + m_x0);
+ }
+
+ int worldToPixY(double y) {
+ return (int) (y * m_dy + m_y0);
+ }
+
+ RasterizedGeometry2DImpl(Geometry geom, double toleranceXY,
+ int rasterSizeBytes) {
+ // //_ASSERT(CanUseAccelerator(geom));
+ init((MultiVertexGeometryImpl) geom._getImpl(), toleranceXY,
+ rasterSizeBytes);
+ }
+
+ static RasterizedGeometry2DImpl createImpl(Geometry geom,
+ double toleranceXY, int rasterSizeBytes) {
+ RasterizedGeometry2DImpl rgImpl = new RasterizedGeometry2DImpl(geom,
+ toleranceXY, rasterSizeBytes);
+
+ return rgImpl;
+ }
+
+ private RasterizedGeometry2DImpl(MultiVertexGeometryImpl geom,
+ double toleranceXY, int rasterSizeBytes) {
+ init(geom, toleranceXY, rasterSizeBytes);
+ }
+
+ static RasterizedGeometry2DImpl createImpl(MultiVertexGeometryImpl geom,
+ double toleranceXY, int rasterSizeBytes) {
+ RasterizedGeometry2DImpl rgImpl = new RasterizedGeometry2DImpl(geom,
+ toleranceXY, rasterSizeBytes);
+ return rgImpl;
+ }
+
+ void init(MultiVertexGeometryImpl geom, double toleranceXY,
+ int rasterSizeBytes) {
+ // _ASSERT(CanUseAccelerator(geom));
+ m_width = Math.max((int) (Math.sqrt(rasterSizeBytes) * 2 + 0.5), 64);
+ m_scanLineSize = (m_width * 2 + 31) / 32; // 2 bits per pixel
+ m_geomEnv = new Envelope2D();
+
+ m_toleranceXY = toleranceXY;
+
+ // calculate bitmap size
+ int size = 0;
+ int width = m_width;
+ int scanLineSize = m_scanLineSize;
+ while (width >= 8) {
+ size += width * scanLineSize;
+ width /= 2;
+ scanLineSize = (width * 2 + 31) / 32;
+ }
+
+ // allocate the bitmap, that contains the base and the mip-levels
+ m_bitmap = new int[size];
+ for (int i = 0; i < size; i++)
+ m_bitmap[i] = 0;
+
+ m_rasterizer = new SimpleRasterizer();
+ ScanCallbackImpl callback = new ScanCallbackImpl(m_bitmap,
+ m_scanLineSize);
+ m_callback = callback;
+ m_rasterizer.setup(m_width, m_width, callback);
+ geom.queryEnvelope2D(m_geomEnv);
+ if (m_geomEnv.getWidth() > m_width * m_geomEnv.getHeight()
+ || m_geomEnv.getHeight() > m_geomEnv.getWidth() * m_width) {
+ // the geometry is thin and the rasterizer is not needed.
+ }
+ m_geomEnv.inflate(toleranceXY, toleranceXY);
+ Envelope2D worldEnv = new Envelope2D();
+
+ Envelope2D pixEnv = Envelope2D
+ .construct(1, 1, m_width - 2, m_width - 2);
+
+ double minWidth = toleranceXY * pixEnv.getWidth(); // min width is such
+ // that the size of
+ // one pixel is
+ // equal to the
+ // tolerance
+ double minHeight = toleranceXY * pixEnv.getHeight();
+
+ worldEnv.setCoords(m_geomEnv.getCenter(),
+ Math.max(minWidth, m_geomEnv.getWidth()),
+ Math.max(minHeight, m_geomEnv.getHeight()));
+
+ m_stroke_half_widthX_pix = worldEnv.getWidth() / pixEnv.getWidth();
+ m_stroke_half_widthY_pix = worldEnv.getHeight() / pixEnv.getHeight();
+
+ // The stroke half width. Later it will be inflated to account for
+ // pixels size.
+ m_stroke_half_width = m_toleranceXY;
+
+ m_transform = new Transformation2D();
+ m_transform.initializeFromRect(worldEnv, pixEnv);// geom to pixels
+
+ switch (geom.getType().value()) {
+ case Geometry.GeometryType.MultiPoint:
+ callback.setColor(m_rasterizer, 2);
+ fillPoints(m_rasterizer, (MultiPointImpl) geom, m_stroke_half_width);
+ break;
+ case Geometry.GeometryType.Polyline:
+ callback.setColor(m_rasterizer, 2);
+ strokeDrawPolyPath(m_rasterizer, (MultiPathImpl) geom._getImpl(),
+ m_stroke_half_width);
+ break;
+ case Geometry.GeometryType.Polygon: {
+ boolean isWinding = false;// NOTE: change when winding is supported
+ callback.setColor(m_rasterizer, 1);
+ fillMultiPath(m_rasterizer, m_transform, (MultiPathImpl) geom, isWinding);
+ callback.setColor(m_rasterizer, 2);
+ strokeDrawPolyPath(m_rasterizer, (MultiPathImpl) geom._getImpl(),
+ m_stroke_half_width);
+ }
+ break;
+ }
+
+ m_dx = m_transform.xx;
+ m_dy = m_transform.yy;
+ m_x0 = m_transform.xd;
+ m_y0 = m_transform.yd;
+ buildLevels();
+ //dbgSaveToBitmap("c:/temp/_dbg.bmp");
+ }
+
+ boolean tryRenderAsSmallEnvelope_(Envelope2D env) {
+ if (!env.isIntersecting(m_geomEnv))
+ return true;
+
+ Envelope2D envPix = new Envelope2D();
+ envPix.setCoords(env);
+ m_transform.transform(env);
+ double strokeHalfWidthPixX = m_stroke_half_widthX_pix;
+ double strokeHalfWidthPixY = m_stroke_half_widthY_pix;
+ if (envPix.getWidth() > 2 * strokeHalfWidthPixX + 1
+ || envPix.getHeight() > 2 * strokeHalfWidthPixY + 1)
+ return false;
+
+ // This envelope is too narrow/small, so that it can be just drawn as a
+ // rectangle using only boundary color.
+
+ envPix.inflate(strokeHalfWidthPixX, strokeHalfWidthPixY);
+ envPix.xmax += 1.0;
+ envPix.ymax += 1.0;// take into account that it does not draw right and
+ // bottom edges.
+
+ m_callback.setColor(m_rasterizer, 2);
+ fillEnvelope(m_rasterizer, envPix);
+ return true;
+ }
+
+ void buildLevels() {
+ m_rasterizer.flush();
+ int iStart = 0;
+ int iStartNext = m_width * m_scanLineSize;
+ int width = m_width;
+ int widthNext = m_width / 2;
+ int scanLineSize = m_scanLineSize;
+ int scanLineSizeNext = (widthNext * 2 + 31) / 32;
+ while (width > 8) {
+ for (int iy = 0; iy < widthNext; iy++) {
+ int iysrc1 = iy * 2;
+ int iysrc2 = iy * 2 + 1;
+ for (int ix = 0; ix < widthNext; ix++) {
+ int ixsrc1 = ix * 2;
+ int ixsrc2 = ix * 2 + 1;
+ int divix1 = ixsrc1 >> 4;
+ int modix1 = (ixsrc1 & 15) * 2;
+ int divix2 = ixsrc2 >> 4;
+ int modix2 = (ixsrc2 & 15) * 2;
+ int res = (m_bitmap[iStart + scanLineSize * iysrc1 + divix1] >> modix1) & 3;
+ res |= (m_bitmap[iStart + scanLineSize * iysrc1 + divix2] >> modix2) & 3;
+ res |= (m_bitmap[iStart + scanLineSize * iysrc2 + divix1] >> modix1) & 3;
+ res |= (m_bitmap[iStart + scanLineSize * iysrc2 + divix2] >> modix2) & 3;
+ int divixDst = ix >> 4;
+ int modixDst = (ix & 15) * 2;
+ m_bitmap[iStartNext + scanLineSizeNext * iy + divixDst] |= res << modixDst;
+ }
+ }
+
+ width = widthNext;
+ scanLineSize = scanLineSizeNext;
+ iStart = iStartNext;
+ widthNext = width / 2;
+ scanLineSizeNext = (widthNext * 2 + 31) / 32;
+ iStartNext = iStart + scanLineSize * width;
+ }
+ }
+
+ @Override
+ public HitType queryPointInGeometry(double x, double y) {
+ if (!m_geomEnv.contains(x, y))
+ return HitType.Outside;
+
+ int ix = worldToPixX(x);
+ int iy = worldToPixY(y);
+ if (ix < 0 || ix >= m_width || iy < 0 || iy >= m_width)
+ return HitType.Outside;
+ int divix = ix >> 4;
+ int modix = (ix & 15) * 2;
+ int res = (m_bitmap[m_scanLineSize * iy + divix] >> modix) & 3;
+ if (res == 0)
+ return HitType.Outside;
+ else if (res == 1)
+ return HitType.Inside;
+ else
+ return HitType.Border;
+ }
+
+ @Override
+ public HitType queryEnvelopeInGeometry(Envelope2D env) {
+ if (!env.intersect(m_geomEnv))
+ return HitType.Outside;
+
+ int ixmin = worldToPixX(env.xmin);
+ int ixmax = worldToPixX(env.xmax);
+ int iymin = worldToPixY(env.ymin);
+ int iymax = worldToPixY(env.ymax);
+ if (ixmin < 0)
+ ixmin = 0;
+ if (iymin < 0)
+ iymin = 0;
+ if (ixmax >= m_width)
+ ixmax = m_width - 1;
+ if (iymax >= m_width)
+ iymax = m_width - 1;
+
+ if (ixmin > ixmax || iymin > iymax)
+ return HitType.Outside;
+
+ int area = Math.max(ixmax - ixmin, 1) * Math.max(iymax - iymin, 1);
+ int iStart = 0;
+ int scanLineSize = m_scanLineSize;
+ int width = m_width;
+ int res = 0;
+ while (true) {
+ if (area < 32 || width < 16) {
+ for (int iy = iymin; iy <= iymax; iy++) {
+ for (int ix = ixmin; ix <= ixmax; ix++) {
+ int divix = ix >> 4;
+ int modix = (ix & 15) * 2;
+ res = (m_bitmap[iStart + scanLineSize * iy + divix] >> modix) & 3; // read
+ // two
+ // bit
+ // color.
+ if (res > 1)
+ return HitType.Border;
+ }
+ }
+
+ if (res == 0)
+ return HitType.Outside;
+ else if (res == 1)
+ return HitType.Inside;
+ }
+
+ iStart += scanLineSize * width;
+ width /= 2;
+ scanLineSize = (width * 2 + 31) / 32;
+ ixmin /= 2;
+ iymin /= 2;
+ ixmax /= 2;
+ iymax /= 2;
+ area = Math.max(ixmax - ixmin, 1) * Math.max(iymax - iymin, 1);
+ }
+ }
+
+ @Override
+ public double getToleranceXY() {
+ return m_toleranceXY;
+ }
+
+ @Override
+ public int getRasterSize() {
+ return m_width * m_scanLineSize;
+ }
+
+ @Override
+ public boolean dbgSaveToBitmap(String fileName) {
+ try {
+ FileOutputStream outfile = new FileOutputStream(fileName);
+
+ int height = m_width;
+ int width = m_width;
+ int sz = 14 + 40 + 4 * m_width * height;
+ // Write the BITMAPFILEHEADER
+ ByteBuffer byteBuffer = ByteBuffer.allocate(sz);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ // byteBuffer.put((byte) 'M');
+ byteBuffer.put((byte) 66);
+ byteBuffer.put((byte) 77);
+ // fwrite("BM", 1, 2, f); //bfType
+ byteBuffer.putInt(sz);
+ // fwrite(&sz, 1, 4, f);//bfSize
+ short zero16 = 0;
+ byteBuffer.putShort(zero16);
+ // fwrite(&zero16, 1, 2, f);//bfReserved1
+ byteBuffer.putShort(zero16);
+ // fwrite(&zero16, 1, 2, f);//bfReserved2
+ int offset = 14 + 40;
+ byteBuffer.putInt(offset);
+ // fwrite(&offset, 1, 4, f);//bfOffBits
+
+ // Write the BITMAPINFOHEADER
+ int biSize = 40;
+ int biWidth = width;
+ int biHeight = -height;
+ short biPlanes = 1;
+ short biBitCount = 32;
+ int biCompression = 0;
+ int biSizeImage = 4 * width * height;
+ int biXPelsPerMeter = 0;
+ int biYPelsPerMeter = 0;
+ int biClrUsed = 0;
+ int biClrImportant = 0;
+ byteBuffer.putInt(biSize);
+ byteBuffer.putInt(biWidth);
+ byteBuffer.putInt(biHeight);
+ byteBuffer.putShort(biPlanes);
+ byteBuffer.putShort(biBitCount);
+ byteBuffer.putInt(biCompression);
+ byteBuffer.putInt(biSizeImage);
+ byteBuffer.putInt(biXPelsPerMeter);
+ byteBuffer.putInt(biYPelsPerMeter);
+ byteBuffer.putInt(biClrUsed);
+ byteBuffer.putInt(biClrImportant);
+
+ int colors[] = { 0xFFFFFFFF, 0xFF000000, 0xFFFF0000, 0xFF00FF00 };
+ // int32_t* rgb4 = (int32_t*)malloc(biSizeImage);
+ for (int y = 0; y < height; y++) {
+ int scanlineIn = y * ((width * 2 + 31) / 32);
+
+ for (int x = 0; x < width; x++) {
+ int res = (m_bitmap[scanlineIn + (x >> 4)] >> ((x & 15) * 2)) & 3;
+ byteBuffer.putInt(colors[res]);
+ }
+ }
+
+ byte[] b = byteBuffer.array();
+ outfile.write(b);
+ outfile.close();
+ return true;
+ } catch (IOException ex) {
+ return false;
+
+ }
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_RASTERIZED_GEOMETRY_2D_IMPL +
+ (m_geomEnv != null ? m_geomEnv.estimateMemorySize() : 0) +
+ (m_transform != null ? m_transform.estimateMemorySize(): 0) +
+ (m_rasterizer != null ? m_rasterizer.estimateMemorySize(): 0) +
+ (m_callback != null ? m_callback.estimateMemorySize(): 0);
+ }
+}
diff --git a/src/com/esri/core/geometry/RelationalOperations.java b/src/main/java/com/esri/core/geometry/RelationalOperations.java
similarity index 80%
rename from src/com/esri/core/geometry/RelationalOperations.java
rename to src/main/java/com/esri/core/geometry/RelationalOperations.java
index 9626b4ca..abf03372 100644
--- a/src/com/esri/core/geometry/RelationalOperations.java
+++ b/src/main/java/com/esri/core/geometry/RelationalOperations.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -894,7 +894,15 @@ private static boolean polygonEqualsPolygon_(Polygon polygon_a,
progress_tracker))
return true;
- return linearPathEqualsLinearPath_(polygon_a, polygon_b, tolerance);
+ double length_a = polygon_a.calculateLength2D();
+ double length_b = polygon_b.calculateLength2D();
+ int max_vertices = Math.max(polygon_a.getPointCount(),
+ polygon_b.getPointCount());
+
+ if (Math.abs(length_a - length_b) > max_vertices * 4.0 * tolerance)
+ return false;
+
+ return linearPathEqualsLinearPath_(polygon_a, polygon_b, tolerance, true);
}
// Returns true if polygon_a is disjoint from polygon_b.
@@ -1131,32 +1139,52 @@ private static boolean polygonTouchesMultiPoint_(Polygon polygon_a,
if (relation == Relation.disjoint || relation == Relation.contains)
return false;
- Envelope2D env_a_inflated = new Envelope2D();
- polygon_a.queryEnvelope2D(env_a_inflated);
- env_a_inflated.inflate(tolerance, tolerance);
+ Envelope2D env_a_inflated = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a_inflated);
+ env_a_inflated.inflate(tolerance, tolerance);
- Point2D ptB = new Point2D();
- boolean b_boundary = false;
+ Point2D ptB;
+ boolean b_boundary = false;
- for (int i = 0; i < multipoint_b.getPointCount(); i++) {
- multipoint_b.getXY(i, ptB);
+ MultiPathImpl polygon_a_impl = (MultiPathImpl)polygon_a._getImpl();
- if (!env_a_inflated.contains(ptB))
- continue;
+ Polygon pa = null;
+ Polygon p_polygon_a = polygon_a;
- PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(
- polygon_a, ptB, tolerance);
+ boolean b_checked_polygon_a_quad_tree = false;
- if (result == PolygonUtils.PiPResult.PiPBoundary)
- b_boundary = true;
- else if (result == PolygonUtils.PiPResult.PiPInside)
- return false;
- }
+ for (int i = 0; i < multipoint_b.getPointCount(); i++)
+ {
+ ptB = multipoint_b.getXY(i);
- if (b_boundary)
- return true;
+ if (env_a_inflated.contains(ptB)) {
- return false;
+ PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(p_polygon_a, ptB, tolerance);
+
+ if (result == PolygonUtils.PiPResult.PiPBoundary)
+ b_boundary = true;
+ else if (result == PolygonUtils.PiPResult.PiPInside)
+ return false;
+ }
+
+ if (!b_checked_polygon_a_quad_tree) {
+ if (PointInPolygonHelper.quadTreeWillHelp(polygon_a, multipoint_b.getPointCount() - 1) && (polygon_a_impl._getAccelerators() == null || polygon_a_impl._getAccelerators().getQuadTree() == null)) {
+ pa = new Polygon();
+ polygon_a.copyTo(pa);
+ ((MultiPathImpl) pa._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
+ p_polygon_a = pa;
+ } else {
+ p_polygon_a = polygon_a;
+ }
+
+ b_checked_polygon_a_quad_tree = true;
+ }
+ }
+
+ if (b_boundary)
+ return true;
+
+ return false;
}
// Returns true if polygon_a crosses multipoint_b.
@@ -1171,36 +1199,59 @@ private static boolean polygonCrossesMultiPoint_(Polygon polygon_a,
if (relation == Relation.disjoint || relation == Relation.contains)
return false;
- Envelope2D env_a = new Envelope2D(), env_a_inflated = new Envelope2D(), env_b = new Envelope2D();
- polygon_a.queryEnvelope2D(env_a);
- multipoint_b.queryEnvelope2D(env_b);
- env_a_inflated.setCoords(env_a);
- env_a_inflated.inflate(tolerance, tolerance);
+ Envelope2D env_a = new Envelope2D(), env_a_inflated = new Envelope2D(), env_b = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a);
+ multipoint_b.queryEnvelope2D(env_b);
+ env_a_inflated.setCoords(env_a);
+ env_a_inflated.inflate(tolerance, tolerance);
- boolean b_interior = false, b_exterior = false;
+ boolean b_interior = false, b_exterior = false;
- Point2D pt_b = new Point2D();
+ Point2D pt_b;
- for (int i = 0; i < multipoint_b.getPointCount(); i++) {
- multipoint_b.getXY(i, pt_b);
+ MultiPathImpl polygon_a_impl = (MultiPathImpl)polygon_a._getImpl();
- if (!env_a_inflated.contains(pt_b)) {
- b_exterior = true;
- } else {
- PolygonUtils.PiPResult result = PolygonUtils
- .isPointInPolygon2D(polygon_a, pt_b, tolerance);
+ Polygon pa = null;
+ Polygon p_polygon_a = polygon_a;
- if (result == PolygonUtils.PiPResult.PiPOutside)
- b_exterior = true;
- else if (result == PolygonUtils.PiPResult.PiPInside)
- b_interior = true;
- }
+ boolean b_checked_polygon_a_quad_tree = false;
- if (b_interior && b_exterior)
- return true;
- }
+ for (int i = 0; i < multipoint_b.getPointCount(); i++)
+ {
+ pt_b = multipoint_b.getXY(i);
- return false;
+ if (!env_a_inflated.contains(pt_b))
+ {
+ b_exterior = true;
+ }
+ else
+ {
+ PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(p_polygon_a, pt_b, tolerance);
+
+ if (result == PolygonUtils.PiPResult.PiPOutside)
+ b_exterior = true;
+ else if (result == PolygonUtils.PiPResult.PiPInside)
+ b_interior = true;
+ }
+
+ if (b_interior && b_exterior)
+ return true;
+
+ if (!b_checked_polygon_a_quad_tree) {
+ if (PointInPolygonHelper.quadTreeWillHelp(polygon_a, multipoint_b.getPointCount() - 1) && (polygon_a_impl._getAccelerators() == null || polygon_a_impl._getAccelerators().getQuadTree() == null)) {
+ pa = new Polygon();
+ polygon_a.copyTo(pa);
+ ((MultiPathImpl) pa._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
+ p_polygon_a = pa;
+ } else {
+ p_polygon_a = polygon_a;
+ }
+
+ b_checked_polygon_a_quad_tree = true;
+ }
+ }
+
+ return false;
}
// Returns true if polygon_a contains multipoint_b.
@@ -1226,25 +1277,45 @@ private static boolean polygonContainsMultiPoint_(Polygon polygon_a,
if (relation == Relation.contains)
return true;
- boolean b_interior = false;
- Point2D ptB = new Point2D();
+ boolean b_interior = false;
+ Point2D ptB;
- for (int i = 0; i < multipoint_b.getPointCount(); i++) {
- multipoint_b.getXY(i, ptB);
+ MultiPathImpl polygon_a_impl = (MultiPathImpl)polygon_a._getImpl();
- if (!env_a.contains(ptB))
- return false;
+ Polygon pa = null;
+ Polygon p_polygon_a = polygon_a;
- PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(
- polygon_a, ptB, tolerance);
+ boolean b_checked_polygon_a_quad_tree = false;
- if (result == PolygonUtils.PiPResult.PiPInside)
- b_interior = true;
- else if (result == PolygonUtils.PiPResult.PiPOutside)
- return false;
- }
+ for (int i = 0; i < multipoint_b.getPointCount(); i++)
+ {
+ ptB = multipoint_b.getXY(i);
- return b_interior;
+ if (!env_a.contains(ptB))
+ return false;
+
+ PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(p_polygon_a, ptB, tolerance);
+
+ if (result == PolygonUtils.PiPResult.PiPInside)
+ b_interior = true;
+ else if (result == PolygonUtils.PiPResult.PiPOutside)
+ return false;
+
+ if (!b_checked_polygon_a_quad_tree) {
+ if (PointInPolygonHelper.quadTreeWillHelp(polygon_a, multipoint_b.getPointCount() - 1) && (polygon_a_impl._getAccelerators() == null || polygon_a_impl._getAccelerators().getQuadTree() == null)) {
+ pa = new Polygon();
+ polygon_a.copyTo(pa);
+ ((MultiPathImpl) pa._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
+ p_polygon_a = pa;
+ } else {
+ p_polygon_a = polygon_a;
+ }
+
+ b_checked_polygon_a_quad_tree = true;
+ }
+ }
+
+ return b_interior;
}
// Returns true if polygon_a equals envelope_b.
@@ -1264,7 +1335,7 @@ private static boolean polygonEqualsEnvelope_(Polygon polygon_a,
Polygon polygon_b = new Polygon();
polygon_b.addEnvelope(envelope_b, false);
- return linearPathEqualsLinearPath_(polygon_a, polygon_b, tolerance);
+ return linearPathEqualsLinearPath_(polygon_a, polygon_b, tolerance, true);
}
// Returns true if polygon_a is disjoint from envelope_b.
@@ -1520,7 +1591,7 @@ private static boolean polylineEqualsPolyline_(Polyline polyline_a,
progress_tracker))
return true;
- return linearPathEqualsLinearPath_(polyline_a, polyline_b, tolerance);
+ return linearPathEqualsLinearPath_(polyline_a, polyline_b, tolerance, false);
}
// Returns true if polyline_a is disjoint from polyline_b.
@@ -1532,6 +1603,14 @@ private static boolean polylineDisjointPolyline_(Polyline polyline_a,
false) == Relation.disjoint)
return true;
+ MultiPathImpl multi_path_impl_a = (MultiPathImpl)polyline_a._getImpl();
+ MultiPathImpl multi_path_impl_b = (MultiPathImpl)polyline_b._getImpl();
+
+ PairwiseIntersectorImpl intersector_paths = new PairwiseIntersectorImpl(multi_path_impl_a, multi_path_impl_b, tolerance, true);
+
+ if (!intersector_paths.next())
+ return false;
+
return !linearPathIntersectsLinearPath_(polyline_a, polyline_b,
tolerance);
}
@@ -1633,7 +1712,7 @@ private static boolean polylineContainsPolyline_(Polyline polyline_a,
false) == Relation.disjoint)
return false;
- return linearPathWithinLinearPath_(polyline_b, polyline_a, tolerance);
+ return linearPathWithinLinearPath_(polyline_b, polyline_a, tolerance, false);
}
// Returns true if polyline_a is disjoint from point_b.
@@ -1691,8 +1770,9 @@ private static boolean polylineTouchesMultiPoint_(Polyline polyline_a,
ProgressTracker progress_tracker) {
// Quick rasterize test to see whether the the geometries are disjoint.
if (tryRasterizedContainsOrDisjoint_(polyline_a, multipoint_b,
- tolerance, false) == Relation.disjoint)
+ tolerance, false) == Relation.disjoint) {
return false;
+ }
SegmentIteratorImpl segIterA = ((MultiPathImpl) polyline_a._getImpl())
.querySegmentIterator();
@@ -1707,26 +1787,59 @@ private static boolean polylineTouchesMultiPoint_(Polyline polyline_a,
envInter.setCoords(env_a);
envInter.intersect(env_b);
- QuadTreeImpl quadTreeA = InternalUtils.buildQuadTree(
- (MultiPathImpl) (polyline_a._getImpl()), envInter);
+ QuadTreeImpl qtA = null;
+ QuadTreeImpl quadTreeA = null;
+ QuadTreeImpl quadTreePathsA = null;
+
+ GeometryAccelerators accel = ((MultiPathImpl) (polyline_a._getImpl()))
+ ._getAccelerators();
+
+ if (accel != null) {
+ quadTreeA = accel.getQuadTree();
+ quadTreePathsA = accel.getQuadTreeForPaths();
+ if (quadTreeA == null) {
+ qtA = InternalUtils.buildQuadTree(
+ (MultiPathImpl) polyline_a._getImpl(), envInter);
+ quadTreeA = qtA;
+ }
+ } else {
+ qtA = InternalUtils.buildQuadTree(
+ (MultiPathImpl) polyline_a._getImpl(), envInter);
+ quadTreeA = qtA;
+ }
+
QuadTreeImpl.QuadTreeIteratorImpl qtIterA = quadTreeA.getIterator();
+ QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsA = null;
+ if (quadTreePathsA != null)
+ qtIterPathsA = quadTreePathsA.getIterator();
+
Point2D ptB = new Point2D(), closest = new Point2D();
boolean b_intersects = false;
double toleranceSq = tolerance * tolerance;
AttributeStreamOfInt8 intersects = new AttributeStreamOfInt8(
multipoint_b.getPointCount());
- for (int i = 0; i < multipoint_b.getPointCount(); i++)
+ for (int i = 0; i < multipoint_b.getPointCount(); i++) {
intersects.write(i, (byte) 0);
+ }
for (int i = 0; i < multipoint_b.getPointCount(); i++) {
multipoint_b.getXY(i, ptB);
- if (!envInter.contains(ptB))
+ if (!envInter.contains(ptB)) {
continue;
+ }
env_b.setCoords(ptB.x, ptB.y, ptB.x, ptB.y);
+
+ if (qtIterPathsA != null) {
+ qtIterPathsA.resetIterator(env_b, tolerance);
+
+ if (qtIterPathsA.next() == -1)
+ continue;
+ }
+
qtIterA.resetIterator(env_b, tolerance);
for (int elementHandleA = qtIterA.next(); elementHandleA != -1; elementHandleA = qtIterA
@@ -1746,16 +1859,18 @@ private static boolean polylineTouchesMultiPoint_(Polyline polyline_a,
}
}
- if (!b_intersects)
+ if (!b_intersects) {
return false;
+ }
MultiPoint boundary_a = (MultiPoint) (polyline_a.getBoundary());
MultiPoint multipoint_b_inter = new MultiPoint();
Point2D pt = new Point2D();
for (int i = 0; i < multipoint_b.getPointCount(); i++) {
- if (intersects.read(i) == 0)
+ if (intersects.read(i) == 0) {
continue;
+ }
multipoint_b.getXY(i, pt);
multipoint_b_inter.add(pt.x, pt.y);
@@ -1771,8 +1886,9 @@ private static boolean polylineCrossesMultiPoint_(Polyline polyline_a,
ProgressTracker progress_tracker) {
// Quick rasterize test to see whether the the geometries are disjoint.
if (tryRasterizedContainsOrDisjoint_(polyline_a, multipoint_b,
- tolerance, false) == Relation.disjoint)
+ tolerance, false) == Relation.disjoint) {
return false;
+ }
SegmentIteratorImpl segIterA = ((MultiPathImpl) polyline_a._getImpl())
.querySegmentIterator();
@@ -1787,19 +1903,43 @@ private static boolean polylineCrossesMultiPoint_(Polyline polyline_a,
envInter.setCoords(env_a);
envInter.intersect(env_b);
- QuadTreeImpl quadTreeA = InternalUtils.buildQuadTree(
- (MultiPathImpl) polyline_a._getImpl(), envInter);
+ QuadTreeImpl qtA = null;
+ QuadTreeImpl quadTreeA = null;
+ QuadTreeImpl quadTreePathsA = null;
+
+ GeometryAccelerators accel = ((MultiPathImpl) (polyline_a._getImpl()))
+ ._getAccelerators();
+
+ if (accel != null) {
+ quadTreeA = accel.getQuadTree();
+ quadTreePathsA = accel.getQuadTreeForPaths();
+ if (quadTreeA == null) {
+ qtA = InternalUtils.buildQuadTree(
+ (MultiPathImpl) polyline_a._getImpl(), envInter);
+ quadTreeA = qtA;
+ }
+ } else {
+ qtA = InternalUtils.buildQuadTree(
+ (MultiPathImpl) polyline_a._getImpl(), envInter);
+ quadTreeA = qtA;
+ }
+
QuadTreeImpl.QuadTreeIteratorImpl qtIterA = quadTreeA.getIterator();
- Point2D ptB = new Point2D(), closest = new Point2D();
+ QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsA = null;
+ if (quadTreePathsA != null)
+ qtIterPathsA = quadTreePathsA.getIterator();
+
+ Point2D ptB = new Point2D(), closest = new Point2D();
boolean b_intersects = false;
boolean b_exterior_found = false;
double toleranceSq = tolerance * tolerance;
AttributeStreamOfInt8 intersects = new AttributeStreamOfInt8(
multipoint_b.getPointCount());
- for (int i = 0; i < multipoint_b.getPointCount(); i++)
+ for (int i = 0; i < multipoint_b.getPointCount(); i++) {
intersects.write(i, (byte) 0);
+ }
for (int i = 0; i < multipoint_b.getPointCount(); i++) {
multipoint_b.getXY(i, ptB);
@@ -1810,6 +1950,16 @@ private static boolean polylineCrossesMultiPoint_(Polyline polyline_a,
}
env_b.setCoords(ptB.x, ptB.y, ptB.x, ptB.y);
+
+ if (qtIterPathsA != null) {
+ qtIterPathsA.resetIterator(env_b, tolerance);
+
+ if (qtIterPathsA.next() == -1) {
+ b_exterior_found = true;
+ continue;
+ }
+ }
+
qtIterA.resetIterator(env_b, tolerance);
boolean b_covered = false;
@@ -1831,20 +1981,23 @@ private static boolean polylineCrossesMultiPoint_(Polyline polyline_a,
}
}
- if (!b_covered)
+ if (!b_covered) {
b_exterior_found = true;
+ }
}
- if (!b_intersects || !b_exterior_found)
+ if (!b_intersects || !b_exterior_found) {
return false;
+ }
MultiPoint boundary_a = (MultiPoint) (polyline_a.getBoundary());
MultiPoint multipoint_b_inter = new MultiPoint();
Point2D pt = new Point2D();
for (int i = 0; i < multipoint_b.getPointCount(); i++) {
- if (intersects.read(i) == 0)
+ if (intersects.read(i) == 0) {
continue;
+ }
multipoint_b.getXY(i, pt);
multipoint_b_inter.add(pt.x, pt.y);
@@ -2083,7 +2236,7 @@ private static boolean polylineContainsEnvelope_(Polyline polyline_a,
polyline_b.startPath(p);
envelope_b.queryCornerByVal(2, p);
polyline_b.lineTo(p);
- return linearPathWithinLinearPath_(polyline_b, polyline_a, tolerance);
+ return linearPathWithinLinearPath_(polyline_b, polyline_a, tolerance, false);
}
// Returns true if polyline_a crosses envelope_b.
@@ -2231,7 +2384,7 @@ private static boolean multiPointContainsMultiPointBrute_(
}
// Returns true if multipoint_a equals point_b.
- private static boolean multiPointEqualsPoint_(MultiPoint multipoint_a,
+ static boolean multiPointEqualsPoint_(MultiPoint multipoint_a,
Point point_b, double tolerance, ProgressTracker progress_tracker) {
Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
multipoint_a.queryEnvelope2D(env_a);
@@ -2598,8 +2751,8 @@ private static boolean pointEqualsEnvelope_(Point2D pt_a, Envelope2D env_b,
}
// Returns true if pt_a is disjoint from env_b.
- private static boolean pointDisjointEnvelope_(Point2D pt_a,
- Envelope2D env_b, double tolerance, ProgressTracker progress_tracker) {
+ static boolean pointDisjointEnvelope_(Point2D pt_a, Envelope2D env_b,
+ double tolerance, ProgressTracker progress_tracker) {
Envelope2D env_b_inflated = new Envelope2D();
env_b_inflated.setCoords(env_b);
env_b_inflated.inflate(tolerance, tolerance);
@@ -2707,7 +2860,7 @@ private static boolean envelopeEqualsEnvelope_(Envelope2D env_a,
}
// Returns true if env_a is disjoint from env_b.
- private static boolean envelopeDisjointEnvelope_(Envelope2D env_a,
+ static boolean envelopeDisjointEnvelope_(Envelope2D env_a,
Envelope2D env_b, double tolerance, ProgressTracker progress_tracker) {
Envelope2D env_b_inflated = new Envelope2D();
env_b_inflated.setCoords(env_b);
@@ -3019,61 +3172,99 @@ private static boolean envelopeCrossesEnvelope_(Envelope2D env_a,
private static boolean polygonDisjointMultiPath_(Polygon polygon_a,
MultiPath multipath_b, double tolerance,
ProgressTracker progress_tracker) {
- Point2D pt_a = new Point2D(), pt_b = new Point2D();
- Envelope2D env_a_inf = new Envelope2D(), env_b_inf = new Envelope2D();
-
- AttributeStreamOfInt32 parts_a = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 parts_b = new AttributeStreamOfInt32(0);
-
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersectorForOGCParts(
- (MultiPathImpl) polygon_a._getImpl(),
- (MultiPathImpl) multipath_b._getImpl(), tolerance,
- parts_a, parts_b);
-
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int path_a = parts_a.get(index_a);
- int path_b = parts_b.get(index_b);
-
- multipath_b.getXY(multipath_b.getPathStart(path_b), pt_b);
- env_a_inf.setCoords(intersector.getRedEnvelope(index_a));
- env_a_inf.inflate(tolerance, tolerance);
-
- if (env_a_inf.contains(pt_b)) {
- PolygonUtils.PiPResult result = PolygonUtils
- .isPointInPolygon2D(polygon_a, pt_b, 0.0);
-
- if (result != PolygonUtils.PiPResult.PiPOutside)
- return false;
- }
-
- if (multipath_b.getType().value() == Geometry.GeometryType.Polygon) {
- polygon_a.getXY(polygon_a.getPathStart(path_a), pt_a);
- env_b_inf.setCoords(intersector.getBlueEnvelope(index_b));
- env_b_inf.inflate(tolerance, tolerance);
-
- if (env_b_inf.contains(pt_a)) {
- PolygonUtils.PiPResult result = PolygonUtils
- .isPointInPolygon2D((Polygon) multipath_b,
- pt_a, 0.0);
-
- if (result != PolygonUtils.PiPResult.PiPOutside)
- return false;
- }
- }
- }
- }
-
- boolean b_intersects = linearPathIntersectsLinearPath_(polygon_a,
- multipath_b, tolerance);
-
- if (b_intersects)
- return false;
-
- return true;
+ Point2D pt_a, pt_b;
+ Envelope2D env_a_inf = new Envelope2D(), env_b_inf = new Envelope2D();
+
+ MultiPathImpl multi_path_impl_a = (MultiPathImpl)polygon_a._getImpl();
+ MultiPathImpl multi_path_impl_b = (MultiPathImpl)multipath_b._getImpl();
+
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(multi_path_impl_a, multi_path_impl_b, tolerance, true);
+
+ if (!intersector.next())
+ return true; // no rings intersect
+
+ boolean b_intersects = linearPathIntersectsLinearPath_(polygon_a, multipath_b, tolerance);
+
+ if (b_intersects)
+ return false;
+
+ Polygon pa = null;
+ Polygon p_polygon_a = polygon_a;
+
+ Polygon pb = null;
+ Polygon p_polygon_b = null;
+
+ if (multipath_b.getType().value() == Geometry.GeometryType.Polygon)
+ p_polygon_b = (Polygon)multipath_b;
+
+ boolean b_checked_polygon_a_quad_tree = false;
+ boolean b_checked_polygon_b_quad_tree = false;
+
+ do
+ {
+ int path_a = intersector.getRedElement();
+ int path_b = intersector.getBlueElement();
+
+ pt_b = multipath_b.getXY(multipath_b.getPathStart(path_b));
+ env_a_inf.setCoords(intersector.getRedEnvelope());
+ env_a_inf.inflate(tolerance, tolerance);
+
+ if (env_a_inf.contains(pt_b))
+ {
+ PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(p_polygon_a, pt_b, 0.0);
+
+ if (result != PolygonUtils.PiPResult.PiPOutside)
+ return false;
+ }
+
+ if (multipath_b.getType().value() == Geometry.GeometryType.Polygon)
+ {
+ pt_a = polygon_a.getXY(polygon_a.getPathStart(path_a));
+ env_b_inf.setCoords(intersector.getBlueEnvelope());
+ env_b_inf.inflate(tolerance, tolerance);
+
+ if (env_b_inf.contains(pt_a))
+ {
+ PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(p_polygon_b, pt_a, 0.0);
+
+ if (result != PolygonUtils.PiPResult.PiPOutside)
+ return false;
+ }
+ }
+
+ if (!b_checked_polygon_a_quad_tree) {
+ if (PointInPolygonHelper.quadTreeWillHelp(polygon_a, multipath_b.getPathCount() - 1) && (multi_path_impl_a._getAccelerators() == null || multi_path_impl_a._getAccelerators().getQuadTree() == null)) {
+ pa = new Polygon();
+ polygon_a.copyTo(pa);
+ ((MultiPathImpl) pa._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
+ p_polygon_a = pa;
+ } else {
+ p_polygon_a = polygon_a;
+ }
+
+ b_checked_polygon_a_quad_tree = true;
+ }
+
+ if (multipath_b.getType().value() == Geometry.GeometryType.Polygon)
+ {
+ if (!b_checked_polygon_b_quad_tree) {
+ Polygon polygon_b = (Polygon) multipath_b;
+ if (PointInPolygonHelper.quadTreeWillHelp(polygon_b, polygon_a.getPathCount() - 1) && (multi_path_impl_b._getAccelerators() == null || multi_path_impl_b._getAccelerators().getQuadTree() == null)) {
+ pb = new Polygon();
+ polygon_b.copyTo(pb);
+ ((MultiPathImpl) pb._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
+ p_polygon_b = pb;
+ } else {
+ p_polygon_b = (Polygon) multipath_b;
+ }
+
+ b_checked_polygon_b_quad_tree = true;
+ }
+ }
+
+ } while (intersector.next());
+
+ return true;
}
// Returns true if env_a inflated contains env_b.
@@ -3351,16 +3542,16 @@ private static boolean multiPointIntersectsMultiPoint_(
// Returns true if multipathA equals multipathB.
private static boolean linearPathEqualsLinearPath_(MultiPath multipathA,
- MultiPath multipathB, double tolerance) {
- return linearPathWithinLinearPath_(multipathA, multipathB, tolerance)
+ MultiPath multipathB, double tolerance, boolean bEnforceOrientation) {
+ return linearPathWithinLinearPath_(multipathA, multipathB, tolerance, bEnforceOrientation)
&& linearPathWithinLinearPath_(multipathB, multipathA,
- tolerance);
+ tolerance, bEnforceOrientation);
}
// Returns true if the segments of multipathA are within the segments of
// multipathB.
private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
- MultiPath multipathB, double tolerance) {
+ MultiPath multipathB, double tolerance, boolean bEnforceOrientation) {
boolean bWithin = true;
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
@@ -3386,10 +3577,33 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
SegmentIteratorImpl segIterB = ((MultiPathImpl) multipathB._getImpl())
.querySegmentIterator();
- QuadTreeImpl quadTreeB = InternalUtils.buildQuadTree(
- ((MultiPathImpl) multipathB._getImpl()), envInter);
+ QuadTreeImpl qtB = null;
+ QuadTreeImpl quadTreeB = null;
+ QuadTreeImpl quadTreePathsB = null;
+
+ GeometryAccelerators accel = ((MultiPathImpl) multipathB._getImpl())
+ ._getAccelerators();
+
+ if (accel != null) {
+ quadTreeB = accel.getQuadTree();
+ quadTreePathsB = accel.getQuadTreeForPaths();
+ if (quadTreeB == null) {
+ qtB = InternalUtils.buildQuadTree(
+ (MultiPathImpl) multipathB._getImpl(), envInter);
+ quadTreeB = qtB;
+ }
+ } else {
+ qtB = InternalUtils.buildQuadTree(
+ (MultiPathImpl) multipathB._getImpl(), envInter);
+ quadTreeB = qtB;
+ }
+
QuadTreeImpl.QuadTreeIteratorImpl qtIterB = quadTreeB.getIterator();
+ QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsB = null;
+ if (quadTreePathsB != null)
+ qtIterPathsB = quadTreePathsB.getIterator();
+
while (segIterA.nextPath()) {
while (segIterA.hasNextSegment()) {
boolean bStringOfSegmentAsCovered = false;
@@ -3401,6 +3615,15 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
return false; // bWithin = false
}
+ if (qtIterPathsB != null) {
+ qtIterPathsB.resetIterator(env_a, tolerance);
+
+ if (qtIterPathsB.next() == -1) {
+ bWithin = false;
+ return false;
+ }
+ }
+
double lengthA = segmentA.calculateLength2D();
qtIterB.resetIterator(segmentA, tolerance);
@@ -3414,7 +3637,7 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
int result = segmentA.intersect(segmentB, null, scalarsA,
scalarsB, tolerance);
- if (result == 2) {
+ if (result == 2 && (!bEnforceOrientation || scalarsB[0] <= scalarsB[1])) {
double scalar_a_0 = scalarsA[0];
double scalar_a_1 = scalarsA[1];
double scalar_b_0 = scalarsB[0];
@@ -3435,8 +3658,8 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
boolean bSegmentACovered = true;
while (bSegmentACovered) {// keep going while the
- // current segmentA is
- // covered.
+ // current segmentA is
+ // covered.
if (segIterA.hasNextSegment()) {
segmentA = segIterA.nextSegment();
lengthA = segmentA.calculateLength2D();
@@ -3444,7 +3667,7 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
result = segmentA.intersect(segmentB, null,
scalarsA, scalarsB, tolerance);
- if (result == 2) {
+ if (result == 2 && (!bEnforceOrientation || scalarsB[0] <= scalarsB[1])) {
scalar_a_0 = scalarsA[0];
scalar_a_1 = scalarsA[1];
@@ -3462,7 +3685,7 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
null, scalarsA, scalarsB,
tolerance);
- if (result == 2) {
+ if (result == 2 && (!bEnforceOrientation || scalarsB[0] <= scalarsB[1])) {
scalar_a_0 = scalarsA[0];
scalar_a_1 = scalarsA[1];
@@ -3501,16 +3724,17 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
}
}
- if (bStringOfSegmentAsCovered)
+ if (bStringOfSegmentAsCovered) {
continue; // no need to check that segmentA is covered
-
+ }
if (ievent == relOps.m_overlap_events.size()) {
return false; // bWithin = false
}
- if (eventIndices.size() - ievent > 1)
+ if (eventIndices.size() - ievent > 1) {
eventIndices.Sort(ievent, eventIndices.size(),
overlapComparer);
+ }
double lastScalar = 0.0;
@@ -3519,8 +3743,9 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
.get(i));
if (overlapEvent.m_scalar_a_0 < lastScalar
- && overlapEvent.m_scalar_a_1 < lastScalar)
+ && overlapEvent.m_scalar_a_1 < lastScalar) {
continue;
+ }
if (lengthA * (overlapEvent.m_scalar_a_0 - lastScalar) > tolerance) {
return false; // bWithin = false
@@ -3528,8 +3753,9 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
lastScalar = overlapEvent.m_scalar_a_1;
if (lengthA * (1.0 - lastScalar) <= tolerance
- || lastScalar == 1.0)
+ || lastScalar == 1.0) {
break;
+ }
}
}
@@ -3568,124 +3794,15 @@ private static boolean linearPathOverlapsLinearPath_(MultiPath multipathA,
if (bIntAExtB && !bIntBExtA)
return !linearPathWithinLinearPath_(multipathB, multipathA,
- tolerance);
+ tolerance, false);
if (bIntBExtA && !bIntAExtB)
return !linearPathWithinLinearPath_(multipathA, multipathB,
- tolerance);
+ tolerance, false);
- return !linearPathWithinLinearPath_(multipathA, multipathB, tolerance)
+ return !linearPathWithinLinearPath_(multipathA, multipathB, tolerance, false)
&& !linearPathWithinLinearPath_(multipathB, multipathA,
- tolerance);
- }
-
- // Returns true if the segments of multipathA touches the segments of
- // multipathB.
- private static boolean linearPathTouchesLinearPath_(MultiPath _multipathA,
- MultiPath _multipathB, double tolerance) {
- MultiPath multipathA;
- MultiPath multipathB;
-
- if (_multipathA.getSegmentCount() > _multipathB.getSegmentCount()) {
- multipathA = _multipathB;
- multipathB = _multipathA;
- } else {
- multipathA = _multipathA;
- multipathB = _multipathB;
- }
-
- SegmentIteratorImpl segIterA = ((MultiPathImpl) multipathA._getImpl())
- .querySegmentIterator();
- SegmentIteratorImpl segIterB = ((MultiPathImpl) multipathB._getImpl())
- .querySegmentIterator();
- double[] scalarsA = new double[2];
- double[] scalarsB = new double[2];
-
- boolean bBoundaryIntersectionFound = false;
-
- Envelope2D env_a = new Envelope2D();
- Envelope2D env_b = new Envelope2D();
- Envelope2D envInter = new Envelope2D();
- multipathA.queryEnvelope2D(env_a);
- multipathB.queryEnvelope2D(env_b);
- env_a.inflate(tolerance, tolerance);
- env_b.inflate(tolerance, tolerance);
- envInter.setCoords(env_a);
- envInter.intersect(env_b);
-
- QuadTreeImpl quadTreeB = InternalUtils.buildQuadTree(
- (MultiPathImpl) multipathB._getImpl(), envInter);
- QuadTreeImpl.QuadTreeIteratorImpl qtIterB = quadTreeB.getIterator();
-
- while (segIterA.nextPath()) {
- boolean bHasEndPointsA = !isClosedPath_(multipathA,
- segIterA.getPathIndex());
-
- while (segIterA.hasNextSegment()) {
- Segment segmentA = segIterA.nextSegment();
- segmentA.queryEnvelope2D(env_a);
-
- if (!env_a.isIntersecting(envInter))
- continue;
-
- double lengthA = segmentA.calculateLength2D();
-
- qtIterB.resetIterator(segmentA, tolerance);
-
- for (int elementHandleB = qtIterB.next(); elementHandleB != -1; elementHandleB = qtIterB
- .next()) {
- int vertex_b = quadTreeB.getElement(elementHandleB);
- segIterB.resetToVertex(vertex_b);
- boolean bHasEndPointsB = !isClosedPath_(multipathB,
- segIterB.getPathIndex());
-
- Segment segmentB = segIterB.nextSegment();
- double lengthB = segmentB.calculateLength2D();
-
- int result = segmentA.intersect(segmentB, null, scalarsA,
- scalarsB, tolerance);
-
- if (result > 0) {
- if (result == 2
- && lengthA * (scalarsA[1] - scalarsA[0]) > tolerance)
- return false;
-
- double scalar_a_0 = scalarsA[0];
- double scalar_b_0 = scalarsB[0];
-
- boolean bTouchesStartA = false, bTouchesEndA = false, bTouchesStartB = false, bTouchesEndB = false;
-
- if (lengthA * scalar_a_0 <= tolerance
- && segIterA.isFirstSegmentInPath())
- bTouchesStartA = true;
-
- if (lengthA * (1.0 - scalar_a_0) <= tolerance
- && segIterA.isLastSegmentInPath())
- bTouchesEndA = true;
-
- if (lengthB * scalar_b_0 <= tolerance
- && segIterB.isFirstSegmentInPath())
- bTouchesStartB = true;
-
- if (lengthB * (1.0 - scalar_b_0) <= tolerance
- && segIterB.isLastSegmentInPath())
- bTouchesEndB = true;
-
- if (((!bTouchesStartA && !bTouchesEndA) || !bHasEndPointsA)
- && ((!bTouchesStartB && !bTouchesEndB) || !bHasEndPointsB))
- return false; // return false if Interior-Interior
- // intersection is found
-
- bBoundaryIntersectionFound = true;
- }
- }
- }
- }
-
- return bBoundaryIntersectionFound; // If we haven't already returned
- // false, then no Interior-Interior
- // intersection has been found.
- // Thus, they touch.
+ tolerance, false);
}
// Returns true the dimension of intersection of _multipathA and
@@ -3732,13 +3849,37 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
Point2D int_point = null;
- if (intersections != null)
+ if (intersections != null) {
int_point = new Point2D();
+ }
+
+ QuadTreeImpl qtB = null;
+ QuadTreeImpl quadTreeB = null;
+ QuadTreeImpl quadTreePathsB = null;
+
+ GeometryAccelerators accel = ((MultiPathImpl) multipathB._getImpl())
+ ._getAccelerators();
+
+ if (accel != null) {
+ quadTreeB = accel.getQuadTree();
+ quadTreePathsB = accel.getQuadTreeForPaths();
+ if (quadTreeB == null) {
+ qtB = InternalUtils.buildQuadTree(
+ (MultiPathImpl) multipathB._getImpl(), envInter);
+ quadTreeB = qtB;
+ }
+ } else {
+ qtB = InternalUtils.buildQuadTree(
+ (MultiPathImpl) multipathB._getImpl(), envInter);
+ quadTreeB = qtB;
+ }
- QuadTreeImpl quadTreeB = InternalUtils.buildQuadTree(
- (MultiPathImpl) multipathB._getImpl(), envInter);
QuadTreeImpl.QuadTreeIteratorImpl qtIterB = quadTreeB.getIterator();
+ QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsB = null;
+ if (quadTreePathsB != null)
+ qtIterPathsB = quadTreePathsB.getIterator();
+
while (segIterA.nextPath()) {
overlapLength = 0.0;
@@ -3746,8 +3887,16 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
Segment segmentA = segIterA.nextSegment();
segmentA.queryEnvelope2D(env_a);
- if (!env_a.isIntersecting(envInter))
+ if (!env_a.isIntersecting(envInter)) {
continue;
+ }
+
+ if (qtIterPathsB != null) {
+ qtIterPathsB.resetIterator(env_a, tolerance);
+
+ if (qtIterPathsB.next() == -1)
+ continue;
+ }
double lengthA = segmentA.calculateLength2D();
@@ -3908,8 +4057,9 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
.get(i));
if (overlapEvent.m_scalar_a_0 < lastScalar
- && overlapEvent.m_scalar_a_1 < lastScalar)
+ && overlapEvent.m_scalar_a_1 < lastScalar) {
continue;
+ }
if (lengthA * (overlapEvent.m_scalar_a_0 - lastScalar) > tolerance) {
overlapLength = lengthA
@@ -3921,10 +4071,10 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
overlapLength = lengthA
* (overlapEvent.m_scalar_a_1 - overlapEvent.m_scalar_a_0); // reset
lastPath = overlapEvent.m_ipath_a;
- } else
+ } else {
overlapLength += lengthA
* (overlapEvent.m_scalar_a_1 - overlapEvent.m_scalar_a_0); // accumulate
-
+ }
if (overlapLength > tolerance) {
dim = 1;
return dim;
@@ -3932,14 +4082,15 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
lastScalar = overlapEvent.m_scalar_a_1;
- if (lastScalar == 1.0)
+ if (lastScalar == 1.0) {
break;
+ }
}
}
- if (lengthA * (1.0 - lastScalar) > tolerance)
+ if (lengthA * (1.0 - lastScalar) > tolerance) {
overlapLength = 0.0; // reset
-
+ }
ievent = 0;
eventIndices.resize(0);
relOps.m_overlap_events.clear();
@@ -3959,30 +4110,23 @@ private static boolean linearPathIntersectsLinearPath_(
SegmentIteratorImpl segIterA = multi_path_impl_a.querySegmentIterator();
SegmentIteratorImpl segIterB = multi_path_impl_b.querySegmentIterator();
- AttributeStreamOfInt32 verticesA = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 verticesB = new AttributeStreamOfInt32(0);
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersector(multi_path_impl_a, multi_path_impl_b,
- tolerance, verticesA, verticesB);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(multi_path_impl_a, multi_path_impl_b, tolerance, false);
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int vertex_a = verticesA.get(index_a);
- int vertex_b = verticesB.get(index_b);
+ while (intersector.next()) {
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
- segIterA.resetToVertex(vertex_a);
- segIterB.resetToVertex(vertex_b);
- Segment segmentA = segIterA.nextSegment();
- Segment segmentB = segIterB.nextSegment();
+ segIterA.resetToVertex(vertex_a);
+ segIterB.resetToVertex(vertex_b);
+ Segment segmentA = segIterA.nextSegment();
+ Segment segmentB = segIterB.nextSegment();
- int result = segmentB.intersect(segmentA, null, null, null,
- tolerance);
+ int result = segmentB.intersect(segmentA, null, null, null,
+ tolerance);
- if (result > 0)
- return true;
+ if (result > 0) {
+ return true;
}
}
@@ -3998,9 +4142,6 @@ private static boolean linearPathIntersectsMultiPoint_(
SegmentIteratorImpl segIterA = ((MultiPathImpl) multipathA._getImpl())
.querySegmentIterator();
- boolean bContained = true;
- boolean bInteriorHitFound = false;
-
Envelope2D env_a = new Envelope2D();
Envelope2D env_b = new Envelope2D();
Envelope2D envInter = new Envelope2D();
@@ -4008,28 +4149,56 @@ private static boolean linearPathIntersectsMultiPoint_(
multipoint_b.queryEnvelope2D(env_b);
env_a.inflate(tolerance, tolerance);
- if (!env_a.contains(env_b))
- bContained = false;
-
env_b.inflate(tolerance, tolerance);
envInter.setCoords(env_a);
envInter.intersect(env_b);
- QuadTreeImpl quadTreeA = InternalUtils.buildQuadTree(
- (MultiPathImpl) multipathA._getImpl(), envInter);
+ QuadTreeImpl qtA = null;
+ QuadTreeImpl quadTreeA = null;
+ QuadTreeImpl quadTreePathsA = null;
+
+ GeometryAccelerators accel = ((MultiPathImpl) multipathA._getImpl())
+ ._getAccelerators();
+
+ if (accel != null) {
+ quadTreeA = accel.getQuadTree();
+ quadTreePathsA = accel.getQuadTreeForPaths();
+ if (quadTreeA == null) {
+ qtA = InternalUtils.buildQuadTree(
+ (MultiPathImpl) multipathA._getImpl(), envInter);
+ quadTreeA = qtA;
+ }
+ } else {
+ qtA = InternalUtils.buildQuadTree(
+ (MultiPathImpl) multipathA._getImpl(), envInter);
+ quadTreeA = qtA;
+ }
+
QuadTreeImpl.QuadTreeIteratorImpl qtIterA = quadTreeA.getIterator();
+
+ QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsA = null;
+ if (quadTreePathsA != null)
+ qtIterPathsA = quadTreePathsA.getIterator();
+
Point2D ptB = new Point2D(), closest = new Point2D();
- boolean b_intersects = false;
double toleranceSq = tolerance * tolerance;
for (int i = 0; i < multipoint_b.getPointCount(); i++) {
multipoint_b.getXY(i, ptB);
- if (!envInter.contains(ptB))
+ if (!envInter.contains(ptB)) {
continue;
+ }
- boolean bPtBContained = false;
env_b.setCoords(ptB.x, ptB.y, ptB.x, ptB.y);
+
+ if (qtIterPathsA != null) {
+ qtIterPathsA.resetIterator(env_b, tolerance);
+
+ if (qtIterPathsA.next() == -1)
+ continue;
+ }
+
qtIterA.resetIterator(env_b, tolerance);
boolean b_covered = false;
@@ -4050,53 +4219,83 @@ private static boolean linearPathIntersectsMultiPoint_(
}
if (b_intersects_all) {
- if (!b_covered)
+ if (!b_covered) {
return false;
+ }
} else {
- if (b_covered)
+ if (b_covered) {
return true;
+ }
}
}
- if (b_intersects_all)
+ if (b_intersects_all) {
return true;
+ }
return false;
}
// Returns true if a segment of multipathA intersects point_b.
- private static boolean linearPathIntersectsPoint_(MultiPath multipathA,
+ static boolean linearPathIntersectsPoint_(MultiPath multipathA,
Point2D ptB, double tolerance) {
- SegmentIterator segIterA = multipathA.querySegmentIterator();
Point2D closest = new Point2D();
double toleranceSq = tolerance * tolerance;
+ SegmentIteratorImpl segIterA = ((MultiPathImpl) multipathA._getImpl())
+ .querySegmentIterator();
+
+ GeometryAccelerators accel = ((MultiPathImpl) multipathA._getImpl())
+ ._getAccelerators();
+
+ if (accel != null) {
+ QuadTreeImpl quadTreeA = accel.getQuadTree();
+ if (quadTreeA != null) {
+ Envelope2D env_b = new Envelope2D();
+ env_b.setCoords(ptB);
+
+ QuadTreeImpl.QuadTreeIteratorImpl qt_iter = quadTreeA
+ .getIterator(env_b, tolerance);
+ for (int e = qt_iter.next(); e != -1; e = qt_iter.next()) {
+ segIterA.resetToVertex(quadTreeA.getElement(e));
+
+ if (segIterA.hasNextSegment()) {
+ Segment segmentA = segIterA.nextSegment();
+
+ double t = segmentA.getClosestCoordinate(ptB, false);
+ segmentA.getCoord2D(t, closest);
+
+ if (Point2D.sqrDistance(ptB, closest) <= toleranceSq) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
Envelope2D env_a = new Envelope2D();
- boolean b_intersects = false;
while (segIterA.nextPath()) {
while (segIterA.hasNextSegment()) {
Segment segmentA = segIterA.nextSegment();
- boolean bHasEndPointsA = !isClosedPath_(multipathA,
- segIterA.getPathIndex());
-
segmentA.queryEnvelope2D(env_a);
env_a.inflate(tolerance, tolerance);
- if (!env_a.contains(ptB))
+ if (!env_a.contains(ptB)) {
continue;
+ }
double t = segmentA.getClosestCoordinate(ptB, false);
segmentA.getCoord2D(t, closest);
if (Point2D.sqrDistance(ptB, closest) <= toleranceSq) {
- b_intersects = true;
- break;
+ return true;
}
}
}
- return b_intersects;
+ return false;
}
private static boolean linearPathContainsPoint_(MultiPath multipathA,
@@ -4290,18 +4489,6 @@ private static boolean checkVerticesForIntersection_(
return false;
}
- // Returns true if the MultiPath is Closed, or if the end points are within
- // a tolerance.
- private static boolean isClosedPath_(MultiPath multipathA, int pathA) {
- if (multipathA.isClosedPath(pathA))
- return true;
-
- return false;
- // Point2D startA = multipathA.get_xy(multipathA.getPathStart(pathA));
- // Point2D endA = multipathA.get_xy(multipathA.getPathEnd(pathA) - 1);
- // return startA.equals(endA);
- }
-
private static boolean polygonTouchesPolygonImpl_(Polygon polygon_a,
Polygon polygon_b, double tolerance, ProgressTracker progressTracker) {
MultiPathImpl polygon_impl_a = (MultiPathImpl) polygon_a._getImpl();
@@ -4313,61 +4500,55 @@ private static boolean polygonTouchesPolygonImpl_(Polygon polygon_a,
SegmentIteratorImpl segIterA = polygon_impl_a.querySegmentIterator();
SegmentIteratorImpl segIterB = polygon_impl_b.querySegmentIterator();
- AttributeStreamOfInt32 verticesA = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 verticesB = new AttributeStreamOfInt32(0);
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersector(polygon_impl_a, polygon_impl_b,
- tolerance, verticesA, verticesB);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polygon_impl_b, tolerance, false);
boolean b_boundaries_intersect = false;
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int vertex_a = verticesA.get(index_a);
- int vertex_b = verticesB.get(index_b);
+ while (intersector.next()) {
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
- segIterA.resetToVertex(vertex_a);
- segIterB.resetToVertex(vertex_b);
- Segment segmentA = segIterA.nextSegment();
- Segment segmentB = segIterB.nextSegment();
-
- int result = segmentB.intersect(segmentA, null, scalarsB,
- scalarsA, tolerance);
+ segIterA.resetToVertex(vertex_a);
+ segIterB.resetToVertex(vertex_b);
+ Segment segmentA = segIterA.nextSegment();
+ Segment segmentB = segIterB.nextSegment();
- if (result == 2) {
- double scalar_a_0 = scalarsA[0];
- double scalar_a_1 = scalarsA[1];
- double length_a = segmentA.calculateLength2D();
+ int result = segmentB.intersect(segmentA, null, scalarsB, scalarsA,
+ tolerance);
- if (b_geometries_simple
- && (scalar_a_1 - scalar_a_0) * length_a > tolerance) {
- // If the line segments overlap along the same
- // direction, then we have an Interior-Interior
- // intersection
- return false;
- }
+ if (result == 2) {
+ double scalar_a_0 = scalarsA[0];
+ double scalar_a_1 = scalarsA[1];
+ double length_a = segmentA.calculateLength2D();
- b_boundaries_intersect = true;
- } else if (result != 0) {
- double scalar_a_0 = scalarsA[0];
- double scalar_b_0 = scalarsB[0];
+ if (b_geometries_simple
+ && (scalar_a_1 - scalar_a_0) * length_a > tolerance) {
+ // If the line segments overlap along the same direction,
+ // then we have an Interior-Interior intersection
+ return false;
+ }
- if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0
- && scalar_b_0 > 0.0 && scalar_b_0 < 1.0)
- return false;
+ b_boundaries_intersect = true;
+ } else if (result != 0) {
+ double scalar_a_0 = scalarsA[0];
+ double scalar_b_0 = scalarsB[0];
- b_boundaries_intersect = true;
+ if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0 && scalar_b_0 > 0.0
+ && scalar_b_0 < 1.0) {
+ return false;
}
+
+ b_boundaries_intersect = true;
}
}
- if (!b_boundaries_intersect)
+ if (!b_boundaries_intersect) {
return false;
+ }
Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D(), envInter = new Envelope2D();
polygon_a.queryEnvelope2D(env_a);
@@ -4383,8 +4564,9 @@ private static boolean polygonTouchesPolygonImpl_(Polygon polygon_a,
if (polygon_a.getPointCount() > 10) {
_polygonA = (Polygon) (Clipper.clip(polygon_a, envInter, tolerance,
0.0));
- if (_polygonA.isEmpty())
+ if (_polygonA.isEmpty()) {
return false;
+ }
} else {
_polygonA = polygon_a;
}
@@ -4392,14 +4574,14 @@ private static boolean polygonTouchesPolygonImpl_(Polygon polygon_a,
if (polygon_b.getPointCount() > 10) {
_polygonB = (Polygon) (Clipper.clip(polygon_b, envInter, tolerance,
0.0));
- if (_polygonB.isEmpty())
+ if (_polygonB.isEmpty()) {
return false;
+ }
} else {
_polygonB = polygon_b;
}
// We just need to determine whether interior_interior is false
-
String scl = "F********";
boolean bRelation = RelationalOperationsMatrix.polygonRelatePolygon_(
_polygonA, _polygonB, tolerance, scl, progressTracker);
@@ -4427,52 +4609,46 @@ private static boolean polygonOverlapsPolygonImpl_(Polygon polygon_a,
SegmentIteratorImpl segIterA = polygon_impl_a.querySegmentIterator();
SegmentIteratorImpl segIterB = polygon_impl_b.querySegmentIterator();
- AttributeStreamOfInt32 verticesA = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 verticesB = new AttributeStreamOfInt32(0);
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersector(polygon_impl_a, polygon_impl_b,
- tolerance, verticesA, verticesB);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polygon_impl_b, tolerance, false);
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int vertex_a = verticesA.get(index_a);
- int vertex_b = verticesB.get(index_b);
+ while (intersector.next()) {
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
- segIterA.resetToVertex(vertex_a);
- segIterB.resetToVertex(vertex_b);
- Segment segmentA = segIterA.nextSegment();
- Segment segmentB = segIterB.nextSegment();
+ segIterA.resetToVertex(vertex_a);
+ segIterB.resetToVertex(vertex_b);
+ Segment segmentA = segIterA.nextSegment();
+ Segment segmentB = segIterB.nextSegment();
- int result = segmentB.intersect(segmentA, null, scalarsB,
- scalarsA, tolerance);
+ int result = segmentB.intersect(segmentA, null, scalarsB, scalarsA,
+ tolerance);
- if (result == 2) {
- double scalar_a_0 = scalarsA[0];
- double scalar_a_1 = scalarsA[1];
- double length_a = segmentA.calculateLength2D();
+ if (result == 2) {
+ double scalar_a_0 = scalarsA[0];
+ double scalar_a_1 = scalarsA[1];
+ double length_a = segmentA.calculateLength2D();
- if (b_geometries_simple
- && (scalar_a_1 - scalar_a_0) * length_a > tolerance) {
- // When the line segments intersect along the same
- // direction, then we have an interior-interior
- // intersection
- bInteriorIntersectionKnown = true;
+ if (b_geometries_simple
+ && (scalar_a_1 - scalar_a_0) * length_a > tolerance) {
+ // When the line segments intersect along the same
+ // direction, then we have an interior-interior intersection
+ bInteriorIntersectionKnown = true;
- if (bIntAExtB && bExtAIntB)
- return true;
+ if (bIntAExtB && bExtAIntB) {
+ return true;
}
- } else if (result != 0) {
- double scalar_a_0 = scalarsA[0];
- double scalar_b_0 = scalarsB[0];
+ }
+ } else if (result != 0) {
+ double scalar_a_0 = scalarsA[0];
+ double scalar_b_0 = scalarsB[0];
- if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0
- && scalar_b_0 > 0.0 && scalar_b_0 < 1.0)
- return true;
+ if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0 && scalar_b_0 > 0.0
+ && scalar_b_0 < 1.0) {
+ return true;
}
}
}
@@ -4490,17 +4666,19 @@ private static boolean polygonOverlapsPolygonImpl_(Polygon polygon_a,
Polygon _polygonB;
StringBuilder scl = new StringBuilder();
- if (!bInteriorIntersectionKnown)
+ if (!bInteriorIntersectionKnown) {
scl.append("T*");
- else
+ } else {
scl.append("**");
+ }
if (bIntAExtB) {
if (polygon_b.getPointCount() > 10) {
_polygonB = (Polygon) (Clipper.clip(polygon_b, envInter,
tolerance, 0.0));
- if (_polygonB.isEmpty())
+ if (_polygonB.isEmpty()) {
return false;
+ }
} else {
_polygonB = polygon_b;
}
@@ -4515,8 +4693,9 @@ private static boolean polygonOverlapsPolygonImpl_(Polygon polygon_a,
if (polygon_a.getPointCount() > 10) {
_polygonA = (Polygon) (Clipper.clip(polygon_a, envInter,
tolerance, 0.0));
- if (_polygonA.isEmpty())
+ if (_polygonA.isEmpty()) {
return false;
+ }
} else {
_polygonA = polygon_a;
}
@@ -4535,71 +4714,180 @@ private static boolean polygonOverlapsPolygonImpl_(Polygon polygon_a,
private static boolean polygonContainsPolygonImpl_(Polygon polygon_a,
Polygon polygon_b, double tolerance, ProgressTracker progressTracker) {
- MultiPathImpl polygon_impl_a = (MultiPathImpl) polygon_a._getImpl();
- MultiPathImpl polygon_impl_b = (MultiPathImpl) polygon_b._getImpl();
-
- SegmentIteratorImpl segIterA = polygon_impl_a.querySegmentIterator();
- SegmentIteratorImpl segIterB = polygon_impl_b.querySegmentIterator();
- AttributeStreamOfInt32 verticesA = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 verticesB = new AttributeStreamOfInt32(0);
- double[] scalarsA = new double[2];
- double[] scalarsB = new double[2];
-
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersector(polygon_impl_a, polygon_impl_b,
- tolerance, verticesA, verticesB);
-
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int vertex_a = verticesA.get(index_a);
- int vertex_b = verticesB.get(index_b);
-
- segIterA.resetToVertex(vertex_a);
- segIterB.resetToVertex(vertex_b);
- Segment segmentA = segIterA.nextSegment();
- Segment segmentB = segIterB.nextSegment();
-
- int result = segmentB.intersect(segmentA, null, scalarsB,
- scalarsA, tolerance);
-
- if (result == 1) {
- double scalar_a_0 = scalarsA[0];
- double scalar_b_0 = scalarsB[0];
-
- if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0
- && scalar_b_0 > 0.0 && scalar_b_0 < 1.0)
- return false;
- }
- }
- }
-
- // We can clip polygon_a to the extent of polyline_b
-
- Envelope2D envBInflated = new Envelope2D();
- polygon_b.queryEnvelope2D(envBInflated);
- envBInflated.inflate(1000.0 * tolerance, 1000.0 * tolerance);
-
- Polygon _polygonA;
-
- if (polygon_a.getPointCount() > 10) {
- _polygonA = (Polygon) (Clipper.clip(polygon_a, envBInflated,
- tolerance, 0.0));
- if (_polygonA.isEmpty())
- return false;
- } else {
- _polygonA = polygon_a;
- }
-
- String scl = "T*****F**"; // If Exterior-Interior is false, then
- // Exterior-Boundary is false
-
- boolean bRelation = RelationalOperationsMatrix.polygonRelatePolygon_(
- _polygonA, polygon_b, tolerance, scl, progressTracker);
- return bRelation;
+ boolean[] b_result_known = new boolean[1];
+ b_result_known[0] = false;
+ boolean res = polygonContainsMultiPath_(polygon_a, polygon_b, tolerance, b_result_known, progressTracker);
+
+ if (b_result_known[0])
+ return res;
+
+ // We can clip polygon_a to the extent of polyline_b
+
+ Envelope2D envBInflated = new Envelope2D();
+ polygon_b.queryEnvelope2D(envBInflated);
+ envBInflated.inflate(1000.0 * tolerance, 1000.0 * tolerance);
+
+ Polygon _polygonA = null;
+
+ if (polygon_a.getPointCount() > 10)
+ {
+ _polygonA = (Polygon)Clipper.clip(polygon_a, envBInflated, tolerance, 0.0);
+ if (_polygonA.isEmpty())
+ return false;
+ }
+ else
+ {
+ _polygonA = polygon_a;
+ }
+
+ boolean bContains = RelationalOperationsMatrix.polygonContainsPolygon_(_polygonA, polygon_b, tolerance, progressTracker);
+ return bContains;
}
+ private static boolean polygonContainsMultiPath_(Polygon polygon_a, MultiPath multi_path_b, double tolerance, boolean[] b_result_known, ProgressTracker progress_tracker)
+ {
+ b_result_known[0] = false;
+
+ MultiPathImpl polygon_impl_a = (MultiPathImpl)polygon_a._getImpl();
+ MultiPathImpl multi_path_impl_b = (MultiPathImpl)multi_path_b._getImpl();
+
+ SegmentIteratorImpl segIterA = polygon_impl_a.querySegmentIterator();
+ SegmentIteratorImpl segIterB = multi_path_impl_b.querySegmentIterator();
+ double[] scalarsA = new double[2];
+ double[] scalarsB = new double[2];
+
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(polygon_impl_a, multi_path_impl_b, tolerance, false);
+ boolean b_boundaries_intersect = false;
+
+ while (intersector.next())
+ {
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
+
+ segIterA.resetToVertex(vertex_a, -1);
+ segIterB.resetToVertex(vertex_b, -1);
+ Segment segmentA = segIterA.nextSegment();
+ Segment segmentB = segIterB.nextSegment();
+
+ int result = segmentB.intersect(segmentA, null, scalarsB, scalarsA, tolerance);
+
+ if (result != 0) {
+ b_boundaries_intersect = true;
+ if (result == 1) {
+ double scalar_a_0 = scalarsA[0];
+ double scalar_b_0 = scalarsB[0];
+
+ if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0 && scalar_b_0 > 0.0 && scalar_b_0 < 1.0) {
+ b_result_known[0] = true;
+ return false;
+ }
+ }
+ }
+ }
+
+ if (!b_boundaries_intersect)
+ {
+ b_result_known[0] = true;
+
+ //boundaries do not intersect
+
+ Envelope2D env_a_inflated = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a_inflated);
+ env_a_inflated.inflate(tolerance, tolerance);
+
+ Polygon pa = null;
+ Polygon p_polygon_a = polygon_a;
+
+ boolean b_checked_polygon_a_quad_tree = false;
+
+ Envelope2D path_env_b = new Envelope2D();
+
+ for (int ipath = 0, npath = multi_path_b.getPathCount(); ipath < npath; ipath++)
+ {
+ if (multi_path_b.getPathSize(ipath) > 0)
+ {
+ multi_path_b.queryPathEnvelope2D(ipath, path_env_b);
+
+ if (env_a_inflated.isIntersecting(path_env_b))
+ {
+ Point2D anyPoint = multi_path_b.getXY(multi_path_b.getPathStart(ipath));
+ int res = PointInPolygonHelper.isPointInPolygon(p_polygon_a, anyPoint, 0);
+ if (res == 0)
+ return false;
+ }
+ else
+ {
+ return false;
+ }
+
+ if (!b_checked_polygon_a_quad_tree) {
+ if (PointInPolygonHelper.quadTreeWillHelp(polygon_a, multi_path_b.getPathCount() - 1) && (polygon_impl_a._getAccelerators() == null || polygon_impl_a._getAccelerators().getQuadTree() == null)) {
+ pa = new Polygon();
+ polygon_a.copyTo(pa);
+ ((MultiPathImpl) pa._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
+ p_polygon_a = pa;
+ } else {
+ p_polygon_a = polygon_a;
+ }
+
+ b_checked_polygon_a_quad_tree = true;
+ }
+ }
+ }
+
+ if (polygon_a.getPathCount() == 1 || multi_path_b.getType().value() == Geometry.GeometryType.Polyline)
+ return true; //boundaries do not intersect. all paths of b are inside of a
+
+ // Polygon A has multiple rings, and Multi_path B is a polygon.
+
+ Polygon polygon_b = (Polygon)multi_path_b;
+
+ Envelope2D env_b_inflated = new Envelope2D();
+ polygon_b.queryEnvelope2D(env_b_inflated);
+ env_b_inflated.inflate(tolerance, tolerance);
+
+ Polygon pb = null;
+ Polygon p_polygon_b = polygon_b;
+
+ boolean b_checked_polygon_b_quad_tree = false;
+
+ Envelope2D path_env_a = new Envelope2D();
+
+ for (int ipath = 0, npath = polygon_a.getPathCount(); ipath < npath; ipath++)
+ {
+ if (polygon_a.getPathSize(ipath) > 0)
+ {
+ polygon_a.queryPathEnvelope2D(ipath, path_env_a);
+
+ if (env_b_inflated.isIntersecting(path_env_a))
+ {
+ Point2D anyPoint = polygon_a.getXY(polygon_a.getPathStart(ipath));
+ int res = PointInPolygonHelper.isPointInPolygon(p_polygon_b, anyPoint, 0);
+ if (res == 1)
+ return false;
+ }
+
+ if (!b_checked_polygon_b_quad_tree) {
+ if (PointInPolygonHelper.quadTreeWillHelp(polygon_b, polygon_a.getPathCount() - 1) && (multi_path_impl_b._getAccelerators() == null || multi_path_impl_b._getAccelerators().getQuadTree() == null)) {
+ pb = new Polygon();
+ polygon_b.copyTo(pb);
+ ((MultiPathImpl) pb._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
+ p_polygon_b = pb;
+ } else {
+ p_polygon_b = polygon_b;
+ }
+
+ b_checked_polygon_b_quad_tree = true;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
private static boolean polygonTouchesPolylineImpl_(Polygon polygon_a,
Polyline polyline_b, double tolerance,
ProgressTracker progressTracker) {
@@ -4608,49 +4896,44 @@ private static boolean polygonTouchesPolylineImpl_(Polygon polygon_a,
SegmentIteratorImpl segIterA = polygon_impl_a.querySegmentIterator();
SegmentIteratorImpl segIterB = polyline_impl_b.querySegmentIterator();
- AttributeStreamOfInt32 verticesA = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 verticesB = new AttributeStreamOfInt32(0);
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersector(polygon_impl_a, polyline_impl_b,
- tolerance, verticesA, verticesB);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polyline_impl_b, tolerance, false);
boolean b_boundaries_intersect = false;
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int vertex_a = verticesA.get(index_a);
- int vertex_b = verticesB.get(index_b);
+ while (intersector.next()) {
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
- segIterA.resetToVertex(vertex_a);
- segIterB.resetToVertex(vertex_b);
- Segment segmentA = segIterA.nextSegment();
- Segment segmentB = segIterB.nextSegment();
-
- int result = segmentB.intersect(segmentA, null, scalarsB,
- scalarsA, tolerance);
+ segIterA.resetToVertex(vertex_a);
+ segIterB.resetToVertex(vertex_b);
+ Segment segmentA = segIterA.nextSegment();
+ Segment segmentB = segIterB.nextSegment();
- if (result == 2) {
- b_boundaries_intersect = true;
- } else if (result != 0) {
- double scalar_a_0 = scalarsA[0];
- double scalar_b_0 = scalarsB[0];
+ int result = segmentB.intersect(segmentA, null, scalarsB, scalarsA,
+ tolerance);
- if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0
- && scalar_b_0 > 0.0 && scalar_b_0 < 1.0)
- return false;
+ if (result == 2) {
+ b_boundaries_intersect = true;
+ } else if (result != 0) {
+ double scalar_a_0 = scalarsA[0];
+ double scalar_b_0 = scalarsB[0];
- b_boundaries_intersect = true;
+ if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0 && scalar_b_0 > 0.0
+ && scalar_b_0 < 1.0) {
+ return false;
}
+
+ b_boundaries_intersect = true;
}
}
- if (!b_boundaries_intersect)
+ if (!b_boundaries_intersect) {
return false;
+ }
Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D(), envInter = new Envelope2D();
polygon_a.queryEnvelope2D(env_a);
@@ -4666,8 +4949,9 @@ private static boolean polygonTouchesPolylineImpl_(Polygon polygon_a,
if (polygon_a.getPointCount() > 10) {
_polygonA = (Polygon) (Clipper.clip(polygon_a, envInter, tolerance,
0.0));
- if (_polygonA.isEmpty())
+ if (_polygonA.isEmpty()) {
return false;
+ }
} else {
_polygonA = polygon_a;
}
@@ -4675,14 +4959,14 @@ private static boolean polygonTouchesPolylineImpl_(Polygon polygon_a,
if (polyline_b.getPointCount() > 10) {
_polylineB = (Polyline) Clipper.clip(polyline_b, envInter,
tolerance, 0.0);
- if (_polylineB.isEmpty())
+ if (_polylineB.isEmpty()) {
return false;
+ }
} else {
_polylineB = polyline_b;
}
// We just need to determine that interior_interior is false
-
String scl = "F********";
boolean bRelation = RelationalOperationsMatrix.polygonRelatePolyline_(
_polygonA, _polylineB, tolerance, scl, progressTracker);
@@ -4698,50 +4982,44 @@ private static boolean polygonCrossesPolylineImpl_(Polygon polygon_a,
SegmentIteratorImpl segIterA = polygon_impl_a.querySegmentIterator();
SegmentIteratorImpl segIterB = polyline_impl_b.querySegmentIterator();
- AttributeStreamOfInt32 verticesA = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 verticesB = new AttributeStreamOfInt32(0);
-
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersector(polygon_impl_a, polyline_impl_b,
- tolerance, verticesA, verticesB);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polyline_impl_b, tolerance, false);
boolean b_boundaries_intersect = false;
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int vertex_a = verticesA.get(index_a);
- int vertex_b = verticesB.get(index_b);
-
- segIterA.resetToVertex(vertex_a);
- segIterB.resetToVertex(vertex_b);
- Segment segmentA = segIterA.nextSegment();
- Segment segmentB = segIterB.nextSegment();
+ while (intersector.next()) {
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
- int result = segmentB.intersect(segmentA, null, scalarsB,
- scalarsA, tolerance);
+ segIterA.resetToVertex(vertex_a);
+ segIterB.resetToVertex(vertex_b);
+ Segment segmentA = segIterA.nextSegment();
+ Segment segmentB = segIterB.nextSegment();
- if (result == 2) {
- b_boundaries_intersect = true;
- } else if (result != 0) {
- double scalar_a_0 = scalarsA[0];
- double scalar_b_0 = scalarsB[0];
+ int result = segmentB.intersect(segmentA, null, scalarsB, scalarsA,
+ tolerance);
- if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0
- && scalar_b_0 > 0.0 && scalar_b_0 < 1.0)
- return true;
+ if (result == 2) {
+ b_boundaries_intersect = true;
+ } else if (result != 0) {
+ double scalar_a_0 = scalarsA[0];
+ double scalar_b_0 = scalarsB[0];
- b_boundaries_intersect = true;
+ if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0 && scalar_b_0 > 0.0
+ && scalar_b_0 < 1.0) {
+ return true;
}
+
+ b_boundaries_intersect = true;
}
}
- if (!b_boundaries_intersect)
+ if (!b_boundaries_intersect) {
return false;
+ }
Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D(), envAInflated = new Envelope2D(), envBInflated = new Envelope2D(), envInter = new Envelope2D();
polygon_a.queryEnvelope2D(env_a);
@@ -4761,8 +5039,9 @@ private static boolean polygonCrossesPolylineImpl_(Polygon polygon_a,
if (polygon_a.getPointCount() > 10) {
_polygonA = (Polygon) (Clipper.clip(polygon_a, envInter,
tolerance, 0.0));
- if (_polygonA.isEmpty())
+ if (_polygonA.isEmpty()) {
return false;
+ }
} else {
_polygonA = polygon_a;
}
@@ -4770,8 +5049,9 @@ private static boolean polygonCrossesPolylineImpl_(Polygon polygon_a,
if (polyline_b.getPointCount() > 10) {
_polylineB = (Polyline) (Clipper.clip(polyline_b, envInter,
tolerance, 0.0));
- if (_polylineB.isEmpty())
+ if (_polylineB.isEmpty()) {
return false;
+ }
} else {
_polylineB = polyline_b;
}
@@ -4793,88 +5073,34 @@ private static boolean polygonCrossesPolylineImpl_(Polygon polygon_a,
private static boolean polygonContainsPolylineImpl_(Polygon polygon_a,
Polyline polyline_b, double tolerance,
ProgressTracker progress_tracker) {
- MultiPathImpl polygon_impl_a = (MultiPathImpl) polygon_a._getImpl();
- MultiPathImpl polyline_impl_b = (MultiPathImpl) polyline_b._getImpl();
-
- SegmentIteratorImpl segIterA = polygon_impl_a.querySegmentIterator();
- SegmentIteratorImpl segIterB = polyline_impl_b.querySegmentIterator();
- AttributeStreamOfInt32 verticesA = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 verticesB = new AttributeStreamOfInt32(0);
- double[] scalarsA = new double[2];
- double[] scalarsB = new double[2];
-
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersector(polygon_impl_a, polyline_impl_b,
- tolerance, verticesA, verticesB);
-
- boolean b_boundaries_intersect = false;
-
- if (intersector != null) {
- while (intersector.next()) {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int vertex_a = verticesA.get(index_a);
- int vertex_b = verticesB.get(index_b);
-
- segIterA.resetToVertex(vertex_a);
- segIterB.resetToVertex(vertex_b);
- Segment segmentA = segIterA.nextSegment();
- Segment segmentB = segIterB.nextSegment();
-
- int result = segmentB.intersect(segmentA, null, scalarsB,
- scalarsA, tolerance);
-
- if (result == 2) {
- b_boundaries_intersect = true;
- // Keep going to see if we find a proper intersection of two
- // segments (means contains is false)
- } else if (result != 0) {
- double scalar_a_0 = scalarsA[0];
- double scalar_b_0 = scalarsB[0];
-
- if (scalar_a_0 > 0.0 && scalar_a_0 < 1.0
- && scalar_b_0 > 0.0 && scalar_b_0 < 1.0)
- return false;
-
- b_boundaries_intersect = true;
- // Keep going to see if we find a proper intersection of two
- // segments (means contains is false)
- }
- }
- }
-
- if (!b_boundaries_intersect) {
- segIterB.resetToVertex(0);
- Segment segmentB = segIterB.nextSegment();
-
- Point2D ptB = new Point2D();
- segmentB.getCoord2D(0.5, ptB);
- return (PolygonUtils.isPointInPolygon2D(polygon_a, ptB, 0.0) == PolygonUtils.PiPResult.PiPInside);
- }
-
- // We can clip polygon_a to the extent of polyline_b
-
- Envelope2D envBInflated = new Envelope2D();
- polyline_b.queryEnvelope2D(envBInflated);
- envBInflated.inflate(1000.0 * tolerance, 1000.0 * tolerance);
-
- Polygon _polygonA;
-
- if (polygon_a.getPointCount() > 10) {
- _polygonA = (Polygon) (Clipper.clip(polygon_a, envBInflated,
- tolerance, 0.0));
- if (_polygonA.isEmpty())
- return false;
- } else {
- _polygonA = polygon_a;
- }
-
- String scl = "T*****F**"; // If Exterior-Interior is false, then
- // Exterior-Boundary is false
- boolean bRelation = RelationalOperationsMatrix.polygonRelatePolyline_(
- _polygonA, polyline_b, tolerance, scl, progress_tracker);
-
- return bRelation;
+ boolean[] b_result_known = new boolean[1];
+ b_result_known[0] = false;
+ boolean res = polygonContainsMultiPath_(polygon_a, polyline_b, tolerance, b_result_known, progress_tracker);
+
+ if (b_result_known[0])
+ return res;
+
+ // We can clip polygon_a to the extent of polyline_b
+
+ Envelope2D envBInflated = new Envelope2D();
+ polyline_b.queryEnvelope2D(envBInflated);
+ envBInflated.inflate(1000.0 * tolerance, 1000.0 * tolerance);
+
+ Polygon _polygonA = null;
+
+ if (polygon_a.getPointCount() > 10)
+ {
+ _polygonA = (Polygon)Clipper.clip(polygon_a, envBInflated, tolerance, 0.0);
+ if (_polygonA.isEmpty())
+ return false;
+ }
+ else
+ {
+ _polygonA = polygon_a;
+ }
+
+ boolean bContains = RelationalOperationsMatrix.polygonContainsPolyline_(_polygonA, polyline_b, tolerance, progress_tracker);
+ return bContains;
}
private static boolean polygonContainsPointImpl_(Polygon polygon_a,
@@ -4899,9 +5125,8 @@ private static boolean polygonTouchesPointImpl_(Polygon polygon_a,
return false;
}
- private static boolean multiPointDisjointPointImpl_(
- MultiPoint multipoint_a, Point2D pt_b, double tolerance,
- ProgressTracker progressTracker) {
+ static boolean multiPointDisjointPointImpl_(MultiPoint multipoint_a,
+ Point2D pt_b, double tolerance, ProgressTracker progressTracker) {
Point2D pt_a = new Point2D();
double tolerance_sq = tolerance * tolerance;
@@ -4921,9 +5146,9 @@ private static final class OverlapEvent {
double m_scalar_a_0;
double m_scalar_a_1;
int m_ivertex_b;
- int m_ipath_b;
- double m_scalar_b_0;
- double m_scalar_b_1;
+// int m_ipath_b;
+// double m_scalar_b_0;
+// double m_scalar_b_1;
static OverlapEvent construct(int ivertex_a, int ipath_a,
double scalar_a_0, double scalar_a_1, int ivertex_b,
@@ -4934,9 +5159,9 @@ static OverlapEvent construct(int ivertex_a, int ipath_a,
overlapEvent.m_scalar_a_0 = scalar_a_0;
overlapEvent.m_scalar_a_1 = scalar_a_1;
overlapEvent.m_ivertex_b = ivertex_b;
- overlapEvent.m_ipath_b = ipath_b;
- overlapEvent.m_scalar_b_0 = scalar_b_0;
- overlapEvent.m_scalar_b_1 = scalar_b_1;
+// overlapEvent.m_ipath_b = ipath_b;
+// overlapEvent.m_scalar_b_0 = scalar_b_0;
+// overlapEvent.m_scalar_b_1 = scalar_b_1;
return overlapEvent;
}
}
@@ -4990,4 +5215,40 @@ int compareOverlapEvents_(int o_1, int o_2) {
return 1;
}
+
+ static final class Accelerate_helper {
+ static boolean accelerate_geometry(Geometry geometry,
+ SpatialReference sr,
+ Geometry.GeometryAccelerationDegree accel_degree) {
+ if (!can_accelerate_geometry(geometry))
+ return false;
+
+ double tol = InternalUtils.calculateToleranceFromGeometry(sr,
+ geometry, false);
+ boolean bAccelerated = false;
+ if (GeometryAccelerators.canUseRasterizedGeometry(geometry))
+ bAccelerated |= ((MultiVertexGeometryImpl) geometry._getImpl())
+ ._buildRasterizedGeometryAccelerator(tol, accel_degree);
+
+ Geometry.Type type = geometry.getType();
+ if ((type == Geometry.Type.Polygon || type == Geometry.Type.Polyline)
+ && GeometryAccelerators.canUseQuadTree(geometry)
+ && accel_degree != Geometry.GeometryAccelerationDegree.enumMild)
+ bAccelerated |= ((MultiVertexGeometryImpl) geometry._getImpl())
+ ._buildQuadTreeAccelerator(accel_degree);
+
+ if ((type == Geometry.Type.Polygon || type == Geometry.Type.Polyline)
+ && GeometryAccelerators.canUseQuadTreeForPaths(geometry)
+ && accel_degree != Geometry.GeometryAccelerationDegree.enumMild)
+ bAccelerated |= ((MultiPathImpl) geometry._getImpl())
+ ._buildQuadTreeForPathsAccelerator(accel_degree);
+
+ return bAccelerated;
+ }
+
+ static boolean can_accelerate_geometry(Geometry geometry) {
+ return GeometryAccelerators.canUseRasterizedGeometry(geometry)
+ || GeometryAccelerators.canUseQuadTree(geometry) || GeometryAccelerators.canUseQuadTreeForPaths(geometry);
+ }
+ }
}
diff --git a/src/main/java/com/esri/core/geometry/RelationalOperationsMatrix.java b/src/main/java/com/esri/core/geometry/RelationalOperationsMatrix.java
new file mode 100644
index 00000000..1d93f5c8
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/RelationalOperationsMatrix.java
@@ -0,0 +1,2876 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+class RelationalOperationsMatrix {
+ private TopoGraph m_topo_graph;
+ private int[] m_matrix;
+ private int[] m_max_dim;
+ private boolean[] m_perform_predicates;
+ private String m_scl;
+ private int m_predicates_half_edge;
+ private int m_predicates_cluster;
+ private int m_predicate_count;
+ private int m_cluster_index_a;
+ private int m_cluster_index_b;
+ private int m_visited_index;
+
+ private interface MatrixPredicate {
+ static final int InteriorInterior = 0;
+ static final int InteriorBoundary = 1;
+ static final int InteriorExterior = 2;
+ static final int BoundaryInterior = 3;
+ static final int BoundaryBoundary = 4;
+ static final int BoundaryExterior = 5;
+ static final int ExteriorInterior = 6;
+ static final int ExteriorBoundary = 7;
+ static final int ExteriorExterior = 8;
+ }
+
+ private interface Predicates {
+ static final int AreaAreaPredicates = 0;
+ static final int AreaLinePredicates = 1;
+ static final int LineLinePredicates = 2;
+ static final int AreaPointPredicates = 3;
+ static final int LinePointPredicates = 4;
+ static final int PointPointPredicates = 5;
+ }
+
+ // Computes the necessary 9 intersection relationships of boundary,
+ // interior, and exterior of geometry_a vs geometry_b for the given scl
+ // string.
+ static boolean relate(Geometry geometry_a, Geometry geometry_b,
+ SpatialReference sr, String scl, ProgressTracker progress_tracker) {
+
+ if (scl.length() != 9)
+ throw new GeometryException("relation string length has to be 9 characters");
+
+ for (int i = 0; i < 9; i++)
+ {
+ char c = scl.charAt(i);
+
+ if (c != '*' && c != 'T' && c != 'F' && c != '0' && c != '1' && c != '2')
+ throw new GeometryException("relation string");
+ }
+
+ int relation = getPredefinedRelation_(scl, geometry_a.getDimension(),
+ geometry_b.getDimension());
+
+ if (relation != RelationalOperations.Relation.unknown)
+ return RelationalOperations.relate(geometry_a, geometry_b, sr,
+ relation, progress_tracker);
+
+ Envelope2D env1 = new Envelope2D();
+ geometry_a.queryEnvelope2D(env1);
+ Envelope2D env2 = new Envelope2D();
+ geometry_b.queryEnvelope2D(env2);
+
+ Envelope2D envMerged = new Envelope2D();
+ envMerged.setCoords(env1);
+ envMerged.merge(env2);
+ double tolerance = InternalUtils.calculateToleranceFromGeometry(sr,
+ envMerged, false);
+
+ Geometry _geometryA = convertGeometry_(geometry_a, tolerance);
+ Geometry _geometryB = convertGeometry_(geometry_b, tolerance);
+
+ if (_geometryA.isEmpty() || _geometryB.isEmpty())
+ return relateEmptyGeometries_(_geometryA, _geometryB, scl);
+
+ int typeA = _geometryA.getType().value();
+ int typeB = _geometryB.getType().value();
+
+ boolean bRelation = false;
+
+ switch (typeA) {
+ case Geometry.GeometryType.Polygon:
+ switch (typeB) {
+ case Geometry.GeometryType.Polygon:
+ bRelation = polygonRelatePolygon_((Polygon) (_geometryA),
+ (Polygon) (_geometryB), tolerance, scl,
+ progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Polyline:
+ bRelation = polygonRelatePolyline_((Polygon) (_geometryA),
+ (Polyline) (_geometryB), tolerance, scl,
+ progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Point:
+ bRelation = polygonRelatePoint_((Polygon) (_geometryA),
+ (Point) (_geometryB), tolerance, scl, progress_tracker);
+ break;
+
+ case Geometry.GeometryType.MultiPoint:
+ bRelation = polygonRelateMultiPoint_((Polygon) (_geometryA),
+ (MultiPoint) (_geometryB), tolerance, scl,
+ progress_tracker);
+ break;
+
+ default:
+ break; // warning fix
+ }
+ break;
+
+ case Geometry.GeometryType.Polyline:
+ switch (typeB) {
+ case Geometry.GeometryType.Polygon:
+ bRelation = polygonRelatePolyline_((Polygon) (_geometryB),
+ (Polyline) (_geometryA), tolerance,
+ getTransposeMatrix_(scl), progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Polyline:
+ bRelation = polylineRelatePolyline_((Polyline) (_geometryA),
+ (Polyline) (_geometryB), tolerance, scl,
+ progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Point:
+ bRelation = polylineRelatePoint_((Polyline) (_geometryA),
+ (Point) (_geometryB), tolerance, scl, progress_tracker);
+ break;
+
+ case Geometry.GeometryType.MultiPoint:
+ bRelation = polylineRelateMultiPoint_((Polyline) (_geometryA),
+ (MultiPoint) (_geometryB), tolerance, scl,
+ progress_tracker);
+ break;
+
+ default:
+ break; // warning fix
+ }
+ break;
+
+ case Geometry.GeometryType.Point:
+ switch (typeB) {
+ case Geometry.GeometryType.Polygon:
+ bRelation = polygonRelatePoint_((Polygon) (_geometryB),
+ (Point) (_geometryA), tolerance,
+ getTransposeMatrix_(scl), progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Polyline:
+ bRelation = polylineRelatePoint_((Polyline) (_geometryB),
+ (Point) (_geometryA), tolerance,
+ getTransposeMatrix_(scl), progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Point:
+ bRelation = pointRelatePoint_((Point) (_geometryA),
+ (Point) (_geometryB), tolerance, scl, progress_tracker);
+ break;
+
+ case Geometry.GeometryType.MultiPoint:
+ bRelation = multiPointRelatePoint_((MultiPoint) (_geometryB),
+ (Point) (_geometryA), tolerance,
+ getTransposeMatrix_(scl), progress_tracker);
+ break;
+
+ default:
+ break; // warning fix
+ }
+ break;
+
+ case Geometry.GeometryType.MultiPoint:
+ switch (typeB) {
+ case Geometry.GeometryType.Polygon:
+ bRelation = polygonRelateMultiPoint_((Polygon) (_geometryB),
+ (MultiPoint) (_geometryA), tolerance,
+ getTransposeMatrix_(scl), progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Polyline:
+ bRelation = polylineRelateMultiPoint_((Polyline) (_geometryB),
+ (MultiPoint) (_geometryA), tolerance,
+ getTransposeMatrix_(scl), progress_tracker);
+ break;
+
+ case Geometry.GeometryType.MultiPoint:
+ bRelation = multiPointRelateMultiPoint_(
+ (MultiPoint) (_geometryA), (MultiPoint) (_geometryB),
+ tolerance, scl, progress_tracker);
+ break;
+
+ case Geometry.GeometryType.Point:
+ bRelation = multiPointRelatePoint_((MultiPoint) (_geometryA),
+ (Point) (_geometryB), tolerance, scl, progress_tracker);
+ break;
+
+ default:
+ break; // warning fix
+ }
+ break;
+ default:
+ bRelation = false;
+ break;
+ }
+
+ return bRelation;
+ }
+
+ private RelationalOperationsMatrix() {
+ m_predicate_count = 0;
+ m_topo_graph = new TopoGraph();
+ m_matrix = new int[9];
+ m_max_dim = new int[9];
+ m_perform_predicates = new boolean[9];
+ m_predicates_half_edge = -1;
+ m_predicates_cluster = -1;
+ }
+
+ // Returns true if the relation holds.
+ static boolean polygonRelatePolygon_(Polygon polygon_a, Polygon polygon_b,
+ double tolerance, String scl, ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setAreaAreaPredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a);
+ polygon_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
+ env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint) {
+ relOps.areaAreaDisjointPredicates_(polygon_a, polygon_b);
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown) {
+ // Quick rasterize test to see whether the the geometries are
+ // disjoint, or if one is contained in the other.
+ int relation = RelationalOperations
+ .tryRasterizedContainsOrDisjoint_(polygon_a, polygon_b,
+ tolerance, false);
+
+ if (relation == RelationalOperations.Relation.disjoint) {
+ relOps.areaAreaDisjointPredicates_(polygon_a, polygon_b);
+ bRelationKnown = true;
+ } else if (relation == RelationalOperations.Relation.contains) {
+ relOps.areaAreaContainsPredicates_(polygon_b);
+ bRelationKnown = true;
+ } else if (relation == RelationalOperations.Relation.within) {
+ relOps.areaAreaWithinPredicates_(polygon_a);
+ bRelationKnown = true;
+ }
+ }
+
+ if (!bRelationKnown) {
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(polygon_a);
+ int geom_b = edit_shape.addGeometry(polygon_b);
+ relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
+ progress_tracker);
+ relOps.computeMatrixTopoGraphHalfEdges_(geom_a, geom_b);
+ relOps.m_topo_graph.removeShape();
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bRelation;
+ }
+
+ // The relation is based on the simplified-Polygon A containing Polygon B, which may be non-simple.
+ static boolean polygonContainsPolygon_(Polygon polygon_a, Polygon polygon_b, double tolerance, ProgressTracker progress_tracker)
+ {
+ assert(!polygon_a.isEmpty());
+ assert(!polygon_b.isEmpty());
+
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_("T*****F**");
+ relOps.setAreaAreaPredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a);
+ polygon_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint)
+ {
+ relOps.areaAreaDisjointPredicates_(polygon_a, polygon_b);
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown)
+ {
+ // Quick rasterize test to see whether the the geometries are disjoint, or if one is contained in the other.
+ int relation = RelationalOperations.tryRasterizedContainsOrDisjoint_(polygon_a, polygon_b, tolerance, false);
+
+ if (relation == RelationalOperations.Relation.disjoint)
+ {
+ relOps.areaAreaDisjointPredicates_(polygon_a, polygon_b);
+ bRelationKnown = true;
+ }
+ else if (relation == RelationalOperations.Relation.contains)
+ {
+ relOps.areaAreaContainsPredicates_(polygon_b);
+ bRelationKnown = true;
+ }
+ else if (relation == RelationalOperations.Relation.within)
+ {
+ relOps.areaAreaWithinPredicates_(polygon_a);
+ bRelationKnown = true;
+ }
+ }
+
+ if (bRelationKnown)
+ {
+ boolean bContains = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bContains;
+ }
+
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(polygon_a);
+ int geom_b = edit_shape.addGeometry(polygon_b);
+
+ CrackAndCluster.execute(edit_shape, tolerance, progress_tracker, false);
+ Polyline boundary_b = (Polyline)edit_shape.getGeometry(geom_b).getBoundary();
+ edit_shape.filterClosePoints(0, true, true);
+ Simplificator.execute(edit_shape, geom_a, -1, false, progress_tracker);
+
+ // Make sure Polygon A has exterior
+ // If the simplified Polygon A does not have interior, then it cannot contain anything.
+ if (edit_shape.getPointCount(geom_a) == 0)
+ return false;
+
+ Simplificator.execute(edit_shape, geom_b, -1, false, progress_tracker);
+
+ relOps.setEditShape_(edit_shape, progress_tracker);
+
+ // We see if the simplified Polygon A contains the simplified Polygon B.
+
+ boolean b_empty = edit_shape.getPointCount(geom_b) == 0;
+
+ if (!b_empty)
+ {//geom_b has interior
+ relOps.computeMatrixTopoGraphHalfEdges_(geom_a, geom_b);
+ relOps.m_topo_graph.removeShape();
+ boolean bContains = relationCompare_(relOps.m_matrix, relOps.m_scl);
+
+ if (!bContains)
+ return bContains;
+ }
+
+ Polygon polygon_simple_a = (Polygon)edit_shape.getGeometry(geom_a);
+ edit_shape = new EditShape();
+ geom_a = edit_shape.addGeometry(polygon_simple_a);
+ geom_b = edit_shape.addGeometry(boundary_b);
+ relOps.setEditShape_(edit_shape, progress_tracker);
+
+ // Check no interior lines of the boundary intersect the exterior
+ relOps.m_predicate_count = 0;
+ relOps.resetMatrix_();
+ relOps.setPredicates_(b_empty ? "T*****F**" : "******F**");
+ relOps.setAreaLinePredicates_();
+
+ relOps.computeMatrixTopoGraphHalfEdges_(geom_a, geom_b);
+ relOps.m_topo_graph.removeShape();
+ boolean bContains = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bContains;
+ }
+
+ // Returns true if the relation holds.
+ static boolean polygonRelatePolyline_(Polygon polygon_a,
+ Polyline polyline_b, double tolerance, String scl,
+ ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setAreaLinePredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a);
+ polyline_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
+ env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint) {
+ relOps.areaLineDisjointPredicates_(polygon_a, polyline_b); // passing polyline
+ // to get boundary
+ // information
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown) {
+ // Quick rasterize test to see whether the the geometries are
+ // disjoint, or if one is contained in the other.
+ int relation = RelationalOperations
+ .tryRasterizedContainsOrDisjoint_(polygon_a, polyline_b,
+ tolerance, false);
+
+ if (relation == RelationalOperations.Relation.disjoint) {
+ relOps.areaLineDisjointPredicates_(polygon_a, polyline_b); // passing
+ // polyline to
+ // get boundary
+ // information
+ bRelationKnown = true;
+ } else if (relation == RelationalOperations.Relation.contains) {
+ relOps.areaLineContainsPredicates_(polygon_a, polyline_b); // passing
+ // polyline to
+ // get boundary
+ // information
+ bRelationKnown = true;
+ }
+ }
+
+ if (!bRelationKnown) {
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(polygon_a);
+ int geom_b = edit_shape.addGeometry(polyline_b);
+ relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
+ progress_tracker);
+ relOps.m_cluster_index_b = relOps.m_topo_graph
+ .createUserIndexForClusters();
+ markClusterEndPoints_(geom_b, relOps.m_topo_graph,
+ relOps.m_cluster_index_b);
+ relOps.computeMatrixTopoGraphHalfEdges_(geom_a, geom_b);
+ relOps.m_topo_graph
+ .deleteUserIndexForClusters(relOps.m_cluster_index_b);
+ relOps.m_topo_graph.removeShape();
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bRelation;
+ }
+
+ static boolean polygonContainsPolyline_(Polygon polygon_a, Polyline polyline_b, double tolerance, ProgressTracker progress_tracker)
+ {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_("T*****F**");
+ relOps.setAreaLinePredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a);
+ polyline_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint)
+ {
+ relOps.areaLineDisjointPredicates_(polygon_a, polyline_b); // passing polyline to get boundary information
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown)
+ {
+ // Quick rasterize test to see whether the the geometries are disjoint, or if one is contained in the other.
+ int relation = RelationalOperations.tryRasterizedContainsOrDisjoint_(polygon_a, polyline_b, tolerance, false);
+
+ if (relation == RelationalOperations.Relation.disjoint)
+ {
+ relOps.areaLineDisjointPredicates_(polygon_a, polyline_b); // passing polyline to get boundary information
+ bRelationKnown = true;
+ }
+ else if (relation == RelationalOperations.Relation.contains)
+ {
+ relOps.areaLineContainsPredicates_(polygon_a, polyline_b); // passing polyline to get boundary information
+ bRelationKnown = true;
+ }
+ }
+
+ if (bRelationKnown)
+ {
+ boolean bContains = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bContains;
+ }
+
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(polygon_a);
+ int geom_b = edit_shape.addGeometry(polyline_b);
+ relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance, progress_tracker);
+
+ // Make sure Polygon A has exterior
+ // If the simplified Polygon A does not have interior, then it cannot contain anything.
+ if (edit_shape.getPointCount(geom_a) == 0)
+ return false;
+
+ relOps.computeMatrixTopoGraphHalfEdges_(geom_a, geom_b);
+ relOps.m_topo_graph.removeShape();
+
+ boolean bContains = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bContains;
+ }
+
+ // Returns true if the relation holds
+ static boolean polygonRelateMultiPoint_(Polygon polygon_a,
+ MultiPoint multipoint_b, double tolerance, String scl,
+ ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setAreaPointPredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a);
+ multipoint_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
+ env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint) {
+ relOps.areaPointDisjointPredicates_(polygon_a);
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown) {
+ // Quick rasterize test to see whether the the geometries are
+ // disjoint, or if one is contained in the other.
+ int relation = RelationalOperations
+ .tryRasterizedContainsOrDisjoint_(polygon_a, multipoint_b,
+ tolerance, false);
+
+ if (relation == RelationalOperations.Relation.disjoint) {
+ relOps.areaPointDisjointPredicates_(polygon_a);
+ bRelationKnown = true;
+ } else if (relation == RelationalOperations.Relation.contains) {
+ relOps.areaPointContainsPredicates_(polygon_a);
+ bRelationKnown = true;
+ }
+ }
+
+ if (!bRelationKnown) {
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(polygon_a);
+ int geom_b = edit_shape.addGeometry(multipoint_b);
+ relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
+ progress_tracker);
+ relOps.computeMatrixTopoGraphClusters_(geom_a, geom_b);
+ relOps.m_topo_graph.removeShape();
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bRelation;
+ }
+
+ // Returns true if the relation holds.
+ static boolean polylineRelatePolyline_(Polyline polyline_a,
+ Polyline polyline_b, double tolerance, String scl,
+ ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setLineLinePredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ polyline_a.queryEnvelope2D(env_a);
+ polyline_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
+ env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint) {
+ relOps.lineLineDisjointPredicates_(polyline_a, polyline_b);
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown) {
+ // Quick rasterize test to see whether the the geometries are
+ // disjoint, or if one is contained in the other.
+ int relation = RelationalOperations
+ .tryRasterizedContainsOrDisjoint_(polyline_a, polyline_b,
+ tolerance, false);
+
+ if (relation == RelationalOperations.Relation.disjoint) {
+ relOps.lineLineDisjointPredicates_(polyline_a, polyline_b);
+ bRelationKnown = true;
+ }
+ }
+
+ if (!bRelationKnown) {
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(polyline_a);
+ int geom_b = edit_shape.addGeometry(polyline_b);
+ relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
+ progress_tracker);
+ relOps.m_cluster_index_a = relOps.m_topo_graph
+ .createUserIndexForClusters();
+ relOps.m_cluster_index_b = relOps.m_topo_graph
+ .createUserIndexForClusters();
+ markClusterEndPoints_(geom_a, relOps.m_topo_graph,
+ relOps.m_cluster_index_a);
+ markClusterEndPoints_(geom_b, relOps.m_topo_graph,
+ relOps.m_cluster_index_b);
+ relOps.computeMatrixTopoGraphHalfEdges_(geom_a, geom_b);
+ relOps.m_topo_graph
+ .deleteUserIndexForClusters(relOps.m_cluster_index_a);
+ relOps.m_topo_graph
+ .deleteUserIndexForClusters(relOps.m_cluster_index_b);
+ relOps.m_topo_graph.removeShape();
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bRelation;
+ }
+
+ // Returns true if the relation holds.
+ static boolean polylineRelateMultiPoint_(Polyline polyline_a,
+ MultiPoint multipoint_b, double tolerance, String scl,
+ ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setLinePointPredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ polyline_a.queryEnvelope2D(env_a);
+ multipoint_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
+ env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint) {
+ relOps.linePointDisjointPredicates_(polyline_a);
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown) {
+ // Quick rasterize test to see whether the the geometries are
+ // disjoint, or if one is contained in the other.
+ int relation = RelationalOperations
+ .tryRasterizedContainsOrDisjoint_(polyline_a, multipoint_b,
+ tolerance, false);
+
+ if (relation == RelationalOperations.Relation.disjoint) {
+ relOps.linePointDisjointPredicates_(polyline_a);
+ bRelationKnown = true;
+ }
+ }
+
+ if (!bRelationKnown) {
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(polyline_a);
+ int geom_b = edit_shape.addGeometry(multipoint_b);
+ relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
+ progress_tracker);
+ relOps.m_cluster_index_a = relOps.m_topo_graph
+ .createUserIndexForClusters();
+ markClusterEndPoints_(geom_a, relOps.m_topo_graph,
+ relOps.m_cluster_index_a);
+ relOps.computeMatrixTopoGraphClusters_(geom_a, geom_b);
+ relOps.m_topo_graph
+ .deleteUserIndexForClusters(relOps.m_cluster_index_a);
+ relOps.m_topo_graph.removeShape();
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bRelation;
+ }
+
+ // Returns true if the relation holds.
+ static boolean multiPointRelateMultiPoint_(MultiPoint multipoint_a,
+ MultiPoint multipoint_b, double tolerance, String scl,
+ ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setPointPointPredicates_();
+
+ Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
+ multipoint_a.queryEnvelope2D(env_a);
+ multipoint_b.queryEnvelope2D(env_b);
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
+ env_a, env_b, tolerance, progress_tracker);
+
+ if (b_disjoint) {
+ relOps.pointPointDisjointPredicates_();
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown) {
+ EditShape edit_shape = new EditShape();
+ int geom_a = edit_shape.addGeometry(multipoint_a);
+ int geom_b = edit_shape.addGeometry(multipoint_b);
+ relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
+ progress_tracker);
+ relOps.computeMatrixTopoGraphClusters_(geom_a, geom_b);
+ relOps.m_topo_graph.removeShape();
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bRelation;
+ }
+
+ // Returns true if the relation holds.
+ static boolean polygonRelatePoint_(Polygon polygon_a, Point point_b,
+ double tolerance, String scl, ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setAreaPointPredicates_();
+
+ Envelope2D env_a = new Envelope2D();
+ polygon_a.queryEnvelope2D(env_a);
+ Point2D pt_b = point_b.getXY();
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.pointDisjointEnvelope_(pt_b, env_a, tolerance, progress_tracker);
+
+ if (b_disjoint)
+ {
+ relOps.areaPointDisjointPredicates_(polygon_a);
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown)
+ {
+ PolygonUtils.PiPResult res = PolygonUtils.isPointInPolygon2D(polygon_a, pt_b, tolerance); // uses accelerator
+
+ if (res == PolygonUtils.PiPResult.PiPInside)
+ {// polygon must have area
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = 2;
+ relOps.m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ relOps.m_matrix[MatrixPredicate.BoundaryExterior] = 1;
+ relOps.m_matrix[MatrixPredicate.ExteriorInterior] = -1;
+ }
+ else if (res == PolygonUtils.PiPResult.PiPBoundary)
+ {
+ relOps.m_matrix[MatrixPredicate.ExteriorInterior] = -1;
+
+ double area = polygon_a.calculateArea2D();
+
+ if (area != 0)
+ {
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ relOps.m_matrix[MatrixPredicate.BoundaryInterior] = 0;
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = 2;
+ relOps.m_matrix[MatrixPredicate.BoundaryExterior] = 1;
+ }
+ else
+ {
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ relOps.m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ relOps.m_matrix[MatrixPredicate.BoundaryExterior] = -1;
+
+ Envelope2D env = new Envelope2D();
+ polygon_a.queryEnvelope2D(env);
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = (env.getHeight() == 0.0 && env.getWidth() == 0.0 ? -1 : 1);
+ }
+ }
+ else
+ {
+ relOps.areaPointDisjointPredicates_(polygon_a);
+ }
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, scl);
+ return bRelation;
+ }
+
+ // Returns true if the relation holds.
+ static boolean polylineRelatePoint_(Polyline polyline_a, Point point_b,
+ double tolerance, String scl, ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setLinePointPredicates_();
+
+ Envelope2D env_a = new Envelope2D();
+ polyline_a.queryEnvelope2D(env_a);
+ Point2D pt_b = point_b.getXY();
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.pointDisjointEnvelope_(pt_b, env_a, tolerance, progress_tracker);
+
+ if (b_disjoint)
+ {
+ relOps.linePointDisjointPredicates_(polyline_a);
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown)
+ {
+ MultiPoint boundary_a = null;
+ boolean b_boundary_contains_point_known = false;
+ boolean b_boundary_contains_point = false;
+
+ if (relOps.m_perform_predicates[MatrixPredicate.InteriorInterior] || relOps.m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ boolean b_intersects = RelationalOperations.linearPathIntersectsPoint_(polyline_a, pt_b, tolerance);
+
+ if (b_intersects)
+ {
+ if (relOps.m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ boundary_a = (MultiPoint)Boundary.calculate(polyline_a, progress_tracker);
+ b_boundary_contains_point = !RelationalOperations.multiPointDisjointPointImpl_(boundary_a, pt_b, tolerance, progress_tracker);
+ b_boundary_contains_point_known = true;
+
+ if (b_boundary_contains_point)
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ else
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ }
+
+ relOps.m_matrix[MatrixPredicate.ExteriorInterior] = -1;
+ }
+ else
+ {
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ relOps.m_matrix[MatrixPredicate.ExteriorInterior] = 0;
+ }
+ }
+
+ if (relOps.m_perform_predicates[MatrixPredicate.BoundaryInterior])
+ {
+ if (boundary_a != null && boundary_a.isEmpty())
+ {
+ relOps.m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ }
+ else
+ {
+ if (!b_boundary_contains_point_known)
+ {
+ if (boundary_a == null)
+ boundary_a = (MultiPoint)Boundary.calculate(polyline_a, progress_tracker);
+
+ b_boundary_contains_point = !RelationalOperations.multiPointDisjointPointImpl_(boundary_a, pt_b, tolerance, progress_tracker);
+ b_boundary_contains_point_known = true;
+ }
+
+ relOps.m_matrix[MatrixPredicate.BoundaryInterior] = (b_boundary_contains_point ? 0 : -1);
+ }
+ }
+
+ if (relOps.m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ if (boundary_a != null && boundary_a.isEmpty())
+ {
+ relOps.m_matrix[MatrixPredicate.BoundaryExterior] = -1;
+ }
+ else
+ {
+ if (b_boundary_contains_point_known && !b_boundary_contains_point)
+ {
+ relOps.m_matrix[MatrixPredicate.BoundaryExterior] = 0;
+ }
+ else
+ {
+ if (boundary_a == null)
+ boundary_a = (MultiPoint)Boundary.calculate(polyline_a, progress_tracker);
+
+ boolean b_boundary_equals_point = RelationalOperations.multiPointEqualsPoint_(boundary_a, point_b, tolerance, progress_tracker);
+ relOps.m_matrix[MatrixPredicate.BoundaryExterior] = (b_boundary_equals_point ? -1 : 0);
+ }
+ }
+ }
+
+ if (relOps.m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ boolean b_has_length = polyline_a.calculateLength2D() != 0;
+
+ if (b_has_length)
+ {
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = 1;
+ }
+ else
+ {
+ // all points are interior
+ MultiPoint interior_a = new MultiPoint(polyline_a.getDescription());
+ interior_a.add(polyline_a, 0, polyline_a.getPointCount());
+ boolean b_interior_equals_point = RelationalOperations.multiPointEqualsPoint_(interior_a, point_b, tolerance, progress_tracker);
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = (b_interior_equals_point ? -1 : 0);
+ }
+ }
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
+ return bRelation;
+ }
+
+ // Returns true if the relation holds.
+ static boolean multiPointRelatePoint_(MultiPoint multipoint_a,
+ Point point_b, double tolerance, String scl,
+ ProgressTracker progress_tracker) {
+ RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
+ relOps.resetMatrix_();
+ relOps.setPredicates_(scl);
+ relOps.setPointPointPredicates_();
+
+ Envelope2D env_a = new Envelope2D();
+ multipoint_a.queryEnvelope2D(env_a);
+ Point2D pt_b = point_b.getXY();
+
+ boolean bRelationKnown = false;
+ boolean b_disjoint = RelationalOperations.pointDisjointEnvelope_(pt_b,
+ env_a, tolerance, progress_tracker);
+
+ if (b_disjoint) {
+ relOps.pointPointDisjointPredicates_();
+ bRelationKnown = true;
+ }
+
+ if (!bRelationKnown) {
+ boolean b_intersects = false;
+ boolean b_multipoint_contained = true;
+ double tolerance_sq = tolerance * tolerance;
+
+ for (int i = 0; i < multipoint_a.getPointCount(); i++) {
+ Point2D pt_a = multipoint_a.getXY(i);
+
+ if (Point2D.sqrDistance(pt_a, pt_b) <= tolerance_sq)
+ b_intersects = true;
+ else
+ b_multipoint_contained = false;
+
+ if (b_intersects && !b_multipoint_contained)
+ break;
+ }
+
+ if (b_intersects) {
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = 0;
+
+ if (!b_multipoint_contained)
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = 0;
+ else
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = -1;
+
+ relOps.m_matrix[MatrixPredicate.ExteriorInterior] = -1;
+ } else {
+ relOps.m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ relOps.m_matrix[MatrixPredicate.InteriorExterior] = 0;
+ relOps.m_matrix[MatrixPredicate.ExteriorInterior] = 0;
+ }
+ }
+
+ boolean bRelation = relationCompare_(relOps.m_matrix, scl);
+ return bRelation;
+ }
+
+ // Returns true if the relation holds.
+ static boolean pointRelatePoint_(Point point_a, Point point_b,
+ double tolerance, String scl, ProgressTracker progress_tracker) {
+ Point2D pt_a = point_a.getXY();
+ Point2D pt_b = point_b.getXY();
+ int[] matrix = new int[9];
+
+ for (int i = 0; i < 9; i++)
+ matrix[i] = -1;
+
+ if (Point2D.sqrDistance(pt_a, pt_b) <= tolerance * tolerance) {
+ matrix[MatrixPredicate.InteriorInterior] = 0;
+ } else {
+ matrix[MatrixPredicate.InteriorExterior] = 0;
+ matrix[MatrixPredicate.ExteriorInterior] = 0;
+ }
+
+ matrix[MatrixPredicate.ExteriorExterior] = 2;
+
+ boolean bRelation = relationCompare_(matrix, scl);
+ return bRelation;
+ }
+
+ // Compares the DE-9I matrix against the scl string.
+ private static boolean relationCompare_(int[] matrix, String scl) {
+ for (int i = 0; i < 9; i++) {
+ switch (scl.charAt(i)) {
+ case 'T':
+ assert (matrix[i] != -2);
+ if (matrix[i] == -1)
+ return false;
+ break;
+
+ case 'F':
+ assert (matrix[i] != -2);
+ if (matrix[i] != -1)
+ return false;
+ break;
+
+ case '0':
+ assert (matrix[i] != -2);
+ if (matrix[i] != 0)
+ return false;
+ break;
+
+ case '1':
+ assert (matrix[i] != -2);
+ if (matrix[i] != 1)
+ return false;
+ break;
+
+ case '2':
+ assert (matrix[i] != -2);
+ if (matrix[i] != 2)
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ static boolean relateEmptyGeometries_(Geometry geometry_a, Geometry geometry_b, String scl)
+ {
+ int[] matrix = new int[9];
+
+ if (geometry_a.isEmpty() && geometry_b.isEmpty())
+ {
+ for (int i = 0; i < 9; i++)
+ matrix[i] = -1;
+
+ return relationCompare_(matrix, scl);
+ }
+
+ boolean b_transpose = false;
+
+ Geometry g_a;
+ Geometry g_b;
+
+ if (!geometry_a.isEmpty())
+ {
+ g_a = geometry_a;
+ g_b = geometry_b;
+ }
+ else
+ {
+ g_a = geometry_b;
+ g_b = geometry_a;
+ b_transpose = true;
+ }
+
+ matrix[MatrixPredicate.InteriorInterior] = -1;
+ matrix[MatrixPredicate.InteriorBoundary] = -1;
+ matrix[MatrixPredicate.BoundaryInterior] = -1;
+ matrix[MatrixPredicate.BoundaryBoundary] = -1;
+ matrix[MatrixPredicate.ExteriorInterior] = -1;
+ matrix[MatrixPredicate.ExteriorBoundary] = -1;
+
+ matrix[MatrixPredicate.ExteriorExterior] = 2;
+
+ int type = g_a.getType().value();
+
+ if (Geometry.isMultiPath(type))
+ {
+ if (type == Geometry.GeometryType.Polygon)
+ {
+ double area = ((Polygon)g_a).calculateArea2D();
+
+ if (area != 0)
+ {
+ matrix[MatrixPredicate.InteriorExterior] = 2;
+ matrix[MatrixPredicate.BoundaryExterior] = 1;
+ }
+ else
+ {
+ matrix[MatrixPredicate.BoundaryExterior] = -1;
+
+ Envelope2D env = new Envelope2D();
+ g_a.queryEnvelope2D(env);
+ matrix[MatrixPredicate.InteriorExterior] = (env.getHeight() == 0.0 && env.getWidth() == 0.0 ? 0 : 1);
+ }
+ }
+ else
+ {
+ boolean b_has_length = ((Polyline)g_a).calculateLength2D() != 0;
+ matrix[MatrixPredicate.InteriorExterior] = (b_has_length ? 1 : 0);
+ matrix[MatrixPredicate.BoundaryExterior] = (Boundary.hasNonEmptyBoundary((Polyline)g_a, null) ? 0 : -1);
+ }
+ }
+ else
+ {
+ matrix[MatrixPredicate.InteriorExterior] = 0;
+ matrix[MatrixPredicate.BoundaryExterior] = -1;
+ }
+
+ if (b_transpose)
+ transposeMatrix_(matrix);
+
+ return relationCompare_(matrix, scl);
+ }
+
+ // Checks whether scl string is a predefined relation.
+ private static int getPredefinedRelation_(String scl, int dim_a, int dim_b) {
+ if (equals_(scl))
+ return RelationalOperations.Relation.equals;
+
+ if (disjoint_(scl))
+ return RelationalOperations.Relation.disjoint;
+
+ if (touches_(scl, dim_a, dim_b))
+ return RelationalOperations.Relation.touches;
+
+ if (crosses_(scl, dim_a, dim_b))
+ return RelationalOperations.Relation.crosses;
+
+ if (contains_(scl))
+ return RelationalOperations.Relation.contains;
+
+ if (overlaps_(scl, dim_a, dim_b))
+ return RelationalOperations.Relation.overlaps;
+
+ return RelationalOperations.Relation.unknown;
+ }
+
+ // Checks whether the scl string is the equals relation.
+ private static boolean equals_(String scl) {
+ // Valid for all
+ if (scl.charAt(0) == 'T' && scl.charAt(1) == '*'
+ && scl.charAt(2) == 'F' && scl.charAt(3) == '*'
+ && scl.charAt(4) == '*' && scl.charAt(5) == 'F'
+ && scl.charAt(6) == 'F' && scl.charAt(7) == 'F'
+ && scl.charAt(8) == '*')
+ return true;
+
+ return false;
+ }
+
+ // Checks whether the scl string is the disjoint relation.
+ private static boolean disjoint_(String scl) {
+ if (scl.charAt(0) == 'F' && scl.charAt(1) == 'F'
+ && scl.charAt(2) == '*' && scl.charAt(3) == 'F'
+ && scl.charAt(4) == 'F' && scl.charAt(5) == '*'
+ && scl.charAt(6) == '*' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+
+ return false;
+ }
+
+ // Checks whether the scl string is the touches relation.
+ private static boolean touches_(String scl, int dim_a, int dim_b) {
+ // Points cant touch
+ if (dim_a == 0 && dim_b == 0)
+ return false;
+
+ if (!(dim_a == 2 && dim_b == 2)) {
+ // Valid for area-Line, Line-Line, area-Point, and Line-Point
+ if (scl.charAt(0) == 'F' && scl.charAt(1) == '*'
+ && scl.charAt(2) == '*' && scl.charAt(3) == 'T'
+ && scl.charAt(4) == '*' && scl.charAt(5) == '*'
+ && scl.charAt(6) == '*' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+
+ if (dim_a == 1 && dim_b == 1) {
+ // Valid for Line-Line
+ if (scl.charAt(0) == 'F' && scl.charAt(1) == 'T'
+ && scl.charAt(2) == '*' && scl.charAt(3) == '*'
+ && scl.charAt(4) == '*' && scl.charAt(5) == '*'
+ && scl.charAt(6) == '*' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+ }
+ }
+
+ // Valid for area-area, area-Line, Line-Line
+
+ if (dim_b != 0) {
+ if (scl.charAt(0) == 'F' && scl.charAt(1) == '*'
+ && scl.charAt(2) == '*' && scl.charAt(3) == '*'
+ && scl.charAt(4) == 'T' && scl.charAt(5) == '*'
+ && scl.charAt(6) == '*' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+ }
+
+ return false;
+ }
+
+ // Checks whether the scl string is the crosses relation.
+ private static boolean crosses_(String scl, int dim_a, int dim_b) {
+ if (dim_a > dim_b) {
+ // Valid for area-Line, area-Point, Line-Point
+ if (scl.charAt(0) == 'T' && scl.charAt(1) == '*'
+ && scl.charAt(2) == '*' && scl.charAt(3) == '*'
+ && scl.charAt(4) == '*' && scl.charAt(5) == '*'
+ && scl.charAt(6) == 'T' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+
+ return false;
+ }
+
+ if (dim_a == 1 && dim_b == 1) {
+ // Valid for Line-Line
+ if (scl.charAt(0) == '0' && scl.charAt(1) == '*'
+ && scl.charAt(2) == '*' && scl.charAt(3) == '*'
+ && scl.charAt(4) == '*' && scl.charAt(5) == '*'
+ && scl.charAt(6) == '*' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+ }
+
+ return false;
+ }
+
+ // Checks whether the scl string is the contains relation.
+ private static boolean contains_(String scl) {
+ // Valid for all
+ if (scl.charAt(0) == 'T' && scl.charAt(1) == '*'
+ && scl.charAt(2) == '*' && scl.charAt(3) == '*'
+ && scl.charAt(4) == '*' && scl.charAt(5) == '*'
+ && scl.charAt(6) == 'F' && scl.charAt(7) == 'F'
+ && scl.charAt(8) == '*')
+ return true;
+
+ return false;
+ }
+
+ // Checks whether the scl string is the overlaps relation.
+ private static boolean overlaps_(String scl, int dim_a, int dim_b) {
+ if (dim_a == dim_b) {
+ if (dim_a != 1) {
+ // Valid for area-area, Point-Point
+ if (scl.charAt(0) == 'T' && scl.charAt(1) == '*'
+ && scl.charAt(2) == 'T' && scl.charAt(3) == '*'
+ && scl.charAt(4) == '*' && scl.charAt(5) == '*'
+ && scl.charAt(6) == 'T' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+
+ return false;
+ }
+
+ // Valid for Line-Line
+ if (scl.charAt(0) == '1' && scl.charAt(1) == '*'
+ && scl.charAt(2) == 'T' && scl.charAt(3) == '*'
+ && scl.charAt(4) == '*' && scl.charAt(5) == '*'
+ && scl.charAt(6) == 'T' && scl.charAt(7) == '*'
+ && scl.charAt(8) == '*')
+ return true;
+ }
+
+ return false;
+ }
+
+ // Marks each cluster of the topoGraph as belonging to an interior vertex of
+ // the geometry and/or a boundary index of the geometry.
+ private static void markClusterEndPoints_(int geometry,
+ TopoGraph topoGraph, int clusterIndex) {
+ int id = topoGraph.getGeometryID(geometry);
+
+ for (int cluster = topoGraph.getFirstCluster(); cluster != -1; cluster = topoGraph.getNextCluster(cluster))
+ {
+ int cluster_parentage = topoGraph.getClusterParentage(cluster);
+
+ if ((cluster_parentage & id) == 0)
+ continue;
+
+ int first_half_edge = topoGraph.getClusterHalfEdge(cluster);
+ if (first_half_edge == -1)
+ {
+ topoGraph.setClusterUserIndex(cluster, clusterIndex, 0);
+ continue;
+ }
+
+ int next_half_edge = first_half_edge;
+ int index = 0;
+
+ do
+ {
+ int half_edge = next_half_edge;
+ int half_edge_parentage = topoGraph.getHalfEdgeParentage(half_edge);
+
+ if ((half_edge_parentage & id) != 0)
+ index++;
+
+ next_half_edge = topoGraph.getHalfEdgeNext(topoGraph.getHalfEdgeTwin(half_edge));
+
+ } while (next_half_edge != first_half_edge);
+
+ topoGraph.setClusterUserIndex(cluster, clusterIndex, index);
+ }
+
+ return;
+ }
+
+ private static String getTransposeMatrix_(String scl) {
+ String transpose = new String();
+ transpose += scl.charAt(0);
+ transpose += scl.charAt(3);
+ transpose += scl.charAt(6);
+ transpose += scl.charAt(1);
+ transpose += scl.charAt(4);
+ transpose += scl.charAt(7);
+ transpose += scl.charAt(2);
+ transpose += scl.charAt(5);
+ transpose += scl.charAt(8);
+ return transpose;
+ }
+
+ // Allocates the matrix array if need be, and sets all entries to -2.
+ // -2: Not Computed
+ // -1: No intersection
+ // 0: 0-dimension intersection
+ // 1: 1-dimension intersection
+ // 2: 2-dimension intersection
+ private void resetMatrix_() {
+ for (int i = 0; i < 9; i++)
+ {
+ m_matrix[i] = -2;
+ m_max_dim[i] = -2;
+ }
+ }
+
+ private static void transposeMatrix_(int[] matrix) {
+ int temp1 = matrix[1];
+ int temp2 = matrix[2];
+ int temp5 = matrix[5];
+
+ matrix[1] = matrix[3];
+ matrix[2] = matrix[6];
+ matrix[5] = matrix[7];
+
+ matrix[3] = temp1;
+ matrix[6] = temp2;
+ matrix[7] = temp5;
+ }
+
+ // Sets the relation predicates from the scl string.
+ private void setPredicates_(String scl) {
+ m_scl = scl;
+
+ for (int i = 0; i < 9; i++) {
+ if (m_scl.charAt(i) != '*') {
+ m_perform_predicates[i] = true;
+ m_predicate_count++;
+ } else
+ m_perform_predicates[i] = false;
+ }
+ }
+
+ // Sets the remaining predicates to false
+ private void setRemainingPredicatesToFalse_() {
+ for (int i = 0; i < 9; i++) {
+ if (m_perform_predicates[i] && m_matrix[i] == -2) {
+ m_matrix[i] = -1;
+ m_perform_predicates[i] = false;
+ }
+ }
+ }
+
+ // Checks whether the predicate is known.
+ private boolean isPredicateKnown_(int predicate) {
+ assert(m_scl.charAt(predicate) != '*');
+
+ if (m_matrix[predicate] == -2)
+ return false;
+
+ if (m_matrix[predicate] == -1)
+ {
+ m_perform_predicates[predicate] = false;
+ m_predicate_count--;
+ return true;
+ }
+
+ if (m_scl.charAt(predicate) != 'T' && m_scl.charAt(predicate) != 'F')
+ {
+ if (m_matrix[predicate] < m_max_dim[predicate])
+ {
+ return false;
+ }
+ else
+ {
+ m_perform_predicates[predicate] = false;
+ m_predicate_count--;
+ return true;
+ }
+ }
+ else
+ {
+ m_perform_predicates[predicate] = false;
+ m_predicate_count--;
+ return true;
+ }
+ }
+
+ // Sets the area-area predicates function.
+ private void setAreaAreaPredicates_() {
+ m_predicates_half_edge = Predicates.AreaAreaPredicates;
+
+ m_max_dim[MatrixPredicate.InteriorInterior] = 2;
+ m_max_dim[MatrixPredicate.InteriorBoundary] = 1;
+ m_max_dim[MatrixPredicate.InteriorExterior] = 2;
+ m_max_dim[MatrixPredicate.BoundaryInterior] = 1;
+ m_max_dim[MatrixPredicate.BoundaryBoundary] = 1;
+ m_max_dim[MatrixPredicate.BoundaryExterior] = 1;
+ m_max_dim[MatrixPredicate.ExteriorInterior] = 2;
+ m_max_dim[MatrixPredicate.ExteriorBoundary] = 1;
+ m_max_dim[MatrixPredicate.ExteriorExterior] = 2;
+
+ // set predicates that are always true/false
+ if (m_perform_predicates[MatrixPredicate.ExteriorExterior])
+ {
+ m_matrix[MatrixPredicate.ExteriorExterior] = 2; // Always true
+ m_perform_predicates[MatrixPredicate.ExteriorExterior] = false;
+ m_predicate_count--;
+ }
+ }
+
+ // Sets the area-line predicate function.
+ private void setAreaLinePredicates_() {
+ m_predicates_half_edge = Predicates.AreaLinePredicates;
+ m_predicates_cluster = Predicates.AreaPointPredicates;
+
+ m_max_dim[MatrixPredicate.InteriorInterior] = 1;
+ m_max_dim[MatrixPredicate.InteriorBoundary] = 0;
+ m_max_dim[MatrixPredicate.InteriorExterior] = 2;
+ m_max_dim[MatrixPredicate.BoundaryInterior] = 1;
+ m_max_dim[MatrixPredicate.BoundaryBoundary] = 0;
+ m_max_dim[MatrixPredicate.BoundaryExterior] = 1;
+ m_max_dim[MatrixPredicate.ExteriorInterior] = 1;
+ m_max_dim[MatrixPredicate.ExteriorBoundary] = 0;
+ m_max_dim[MatrixPredicate.ExteriorExterior] = 2;
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorExterior])
+ {
+ m_matrix[MatrixPredicate.ExteriorExterior] = 2; // Always true
+ m_perform_predicates[MatrixPredicate.ExteriorExterior] = false;
+ m_predicate_count--;
+ }
+ }
+
+ // Sets the line-line predicates function.
+ private void setLineLinePredicates_() {
+ m_predicates_half_edge = Predicates.LineLinePredicates;
+ m_predicates_cluster = Predicates.LinePointPredicates;
+
+ m_max_dim[MatrixPredicate.InteriorInterior] = 1;
+ m_max_dim[MatrixPredicate.InteriorBoundary] = 0;
+ m_max_dim[MatrixPredicate.InteriorExterior] = 1;
+ m_max_dim[MatrixPredicate.BoundaryInterior] = 0;
+ m_max_dim[MatrixPredicate.BoundaryBoundary] = 0;
+ m_max_dim[MatrixPredicate.BoundaryExterior] = 0;
+ m_max_dim[MatrixPredicate.ExteriorInterior] = 1;
+ m_max_dim[MatrixPredicate.ExteriorBoundary] = 0;
+ m_max_dim[MatrixPredicate.ExteriorExterior] = 2;
+
+ // set predicates that are always true/false
+ if (m_perform_predicates[MatrixPredicate.ExteriorExterior])
+ {
+ m_matrix[MatrixPredicate.ExteriorExterior] = 2; // Always true
+ m_perform_predicates[MatrixPredicate.ExteriorExterior] = false;
+ m_predicate_count--;
+ }
+ }
+
+ // Sets the area-point predicate function.
+ private void setAreaPointPredicates_() {
+ m_predicates_cluster = Predicates.AreaPointPredicates;
+
+ m_max_dim[MatrixPredicate.InteriorInterior] = 0;
+ m_max_dim[MatrixPredicate.InteriorBoundary] = -1;
+ m_max_dim[MatrixPredicate.InteriorExterior] = 2;
+ m_max_dim[MatrixPredicate.BoundaryInterior] = 0;
+ m_max_dim[MatrixPredicate.BoundaryBoundary] = -1;
+ m_max_dim[MatrixPredicate.BoundaryExterior] = 1;
+ m_max_dim[MatrixPredicate.ExteriorInterior] = 0;
+ m_max_dim[MatrixPredicate.ExteriorBoundary] = -1;
+ m_max_dim[MatrixPredicate.ExteriorExterior] = 2;
+
+ // set predicates that are always true/false
+ if (m_perform_predicates[MatrixPredicate.InteriorBoundary])
+ {
+ m_matrix[MatrixPredicate.InteriorBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.InteriorBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryBoundary])
+ {
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.BoundaryBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
+ {
+ m_matrix[MatrixPredicate.ExteriorBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.ExteriorBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorExterior])
+ {
+ m_matrix[MatrixPredicate.ExteriorExterior] = 2; // Always true
+ m_perform_predicates[MatrixPredicate.ExteriorExterior] = false;
+ m_predicate_count--;
+ }
+ }
+
+ // Sets the line-point predicates function.
+ private void setLinePointPredicates_() {
+ m_predicates_cluster = Predicates.LinePointPredicates;
+
+ m_max_dim[MatrixPredicate.InteriorInterior] = 0;
+ m_max_dim[MatrixPredicate.InteriorBoundary] = -1;
+ m_max_dim[MatrixPredicate.InteriorExterior] = 1;
+ m_max_dim[MatrixPredicate.BoundaryInterior] = 0;
+ m_max_dim[MatrixPredicate.BoundaryBoundary] = -1;
+ m_max_dim[MatrixPredicate.BoundaryExterior] = 0;
+ m_max_dim[MatrixPredicate.ExteriorInterior] = 0;
+ m_max_dim[MatrixPredicate.ExteriorBoundary] = -1;
+ m_max_dim[MatrixPredicate.ExteriorExterior] = 2;
+
+ // set predicates that are always true/false
+ if (m_perform_predicates[MatrixPredicate.InteriorBoundary])
+ {
+ m_matrix[MatrixPredicate.InteriorBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.InteriorBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryBoundary])
+ {
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.BoundaryBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
+ {
+ m_matrix[MatrixPredicate.ExteriorBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.ExteriorBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorExterior])
+ {
+ m_matrix[MatrixPredicate.ExteriorExterior] = 2; // Always true
+ m_perform_predicates[MatrixPredicate.ExteriorExterior] = false;
+ m_predicate_count--;
+ }
+ }
+
+ // Sets the point-point predicates function.
+ private void setPointPointPredicates_() {
+ m_predicates_cluster = Predicates.PointPointPredicates;
+
+ m_max_dim[MatrixPredicate.InteriorInterior] = 0;
+ m_max_dim[MatrixPredicate.InteriorBoundary] = -1;
+ m_max_dim[MatrixPredicate.InteriorExterior] = 0;
+ m_max_dim[MatrixPredicate.BoundaryInterior] = -1;
+ m_max_dim[MatrixPredicate.BoundaryBoundary] = -1;
+ m_max_dim[MatrixPredicate.BoundaryExterior] = -1;
+ m_max_dim[MatrixPredicate.ExteriorInterior] = 0;
+ m_max_dim[MatrixPredicate.ExteriorBoundary] = -1;
+ m_max_dim[MatrixPredicate.ExteriorExterior] = 2;
+
+ // set predicates that are always true/false
+ if (m_perform_predicates[MatrixPredicate.InteriorBoundary])
+ {
+ m_matrix[MatrixPredicate.InteriorBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.InteriorBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryInterior])
+ {
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.BoundaryInterior] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryBoundary])
+ {
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.BoundaryBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ m_matrix[MatrixPredicate.BoundaryExterior] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.BoundaryExterior] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
+ {
+ m_matrix[MatrixPredicate.ExteriorBoundary] = -1; // Always false
+ m_perform_predicates[MatrixPredicate.ExteriorBoundary] = false;
+ m_predicate_count--;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorExterior])
+ {
+ m_matrix[MatrixPredicate.ExteriorExterior] = 2; // Always true
+ m_perform_predicates[MatrixPredicate.ExteriorExterior] = false;
+ m_predicate_count--;
+ }
+ }
+
+ // Invokes the 9 relational predicates of area vs area.
+ private boolean areaAreaPredicates_(int half_edge, int id_a, int id_b) {
+ boolean bRelationKnown = true;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior]) {
+ interiorAreaInteriorArea_(half_edge, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.InteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorBoundary]) {
+ interiorAreaBoundaryArea_(half_edge, id_a,
+ MatrixPredicate.InteriorBoundary);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.InteriorBoundary);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior]) {
+ interiorAreaExteriorArea_(half_edge, id_a, id_b,
+ MatrixPredicate.InteriorExterior);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.InteriorExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryInterior]) {
+ interiorAreaBoundaryArea_(half_edge, id_b,
+ MatrixPredicate.BoundaryInterior);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.BoundaryInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryBoundary]) {
+ boundaryAreaBoundaryArea_(half_edge, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.BoundaryBoundary);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior]) {
+ boundaryAreaExteriorArea_(half_edge, id_a, id_b,
+ MatrixPredicate.BoundaryExterior);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.BoundaryExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior]) {
+ interiorAreaExteriorArea_(half_edge, id_b, id_a,
+ MatrixPredicate.ExteriorInterior);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.ExteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary]) {
+ boundaryAreaExteriorArea_(half_edge, id_b, id_a,
+ MatrixPredicate.ExteriorBoundary);
+ bRelationKnown &= isPredicateKnown_(
+ MatrixPredicate.ExteriorBoundary);
+ }
+
+ return bRelationKnown;
+ }
+
+ private void areaAreaDisjointPredicates_(Polygon polygon_a, Polygon polygon_b) {
+ m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ m_matrix[MatrixPredicate.InteriorBoundary] = -1;
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
+
+ areaGeomContainsOrDisjointPredicates_(polygon_a, m_perform_predicates[MatrixPredicate.InteriorExterior] ? MatrixPredicate.InteriorExterior : -1, m_scl.charAt(MatrixPredicate.InteriorExterior), m_perform_predicates[MatrixPredicate.BoundaryExterior] ? MatrixPredicate.BoundaryExterior : -1, m_scl.charAt(MatrixPredicate.BoundaryExterior));
+ areaGeomContainsOrDisjointPredicates_(polygon_b, m_perform_predicates[MatrixPredicate.ExteriorInterior] ? MatrixPredicate.ExteriorInterior : -1, m_scl.charAt(MatrixPredicate.ExteriorInterior), m_perform_predicates[MatrixPredicate.ExteriorBoundary] ? MatrixPredicate.ExteriorBoundary : -1, m_scl.charAt(MatrixPredicate.ExteriorBoundary));
+ }
+
+ private void areaGeomContainsOrDisjointPredicates_(Polygon polygon, int matrix_interior, char c1, int matrix_boundary, char c2)
+ {
+ if (matrix_interior != -1 || matrix_boundary != -1)
+ {
+ boolean has_area = ((c1 != 'T' && c1 != 'F' && matrix_interior != -1) || (c2 != 'T' && c2 != 'F' && matrix_boundary != -1) ? polygon.calculateArea2D() != 0 : true);
+
+ if (has_area)
+ {
+ if (matrix_interior != -1)
+ m_matrix[matrix_interior] = 2;
+ if (matrix_boundary != -1)
+ m_matrix[matrix_boundary] = 1;
+ }
+ else
+ {
+ if (matrix_boundary != -1)
+ m_matrix[matrix_boundary] = -1;
+
+ if (matrix_interior != -1)
+ {
+ Envelope2D env = new Envelope2D();
+ polygon.queryEnvelope2D(env);
+ m_matrix[matrix_interior] = (env.getHeight() == 0.0 && env.getWidth() == 0.0 ? 0 : 1);
+ }
+ }
+ }
+ }
+
+ private void areaAreaContainsPredicates_(Polygon polygon_b) {
+ m_matrix[MatrixPredicate.InteriorExterior] = 2; // im assuming its a proper contains.
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
+ m_matrix[MatrixPredicate.BoundaryExterior] = 1;
+ m_matrix[MatrixPredicate.ExteriorInterior] = -1;
+ m_matrix[MatrixPredicate.ExteriorBoundary] = -1;
+
+ areaGeomContainsOrDisjointPredicates_(polygon_b, m_perform_predicates[MatrixPredicate.InteriorInterior] ? MatrixPredicate.InteriorInterior : -1, m_scl.charAt(MatrixPredicate.InteriorInterior), m_perform_predicates[MatrixPredicate.InteriorBoundary] ? MatrixPredicate.InteriorBoundary : -1, m_scl.charAt(MatrixPredicate.InteriorBoundary));
+
+ // all other predicates should already be set by set_area_area_predicates
+ }
+
+ private void areaAreaWithinPredicates_(Polygon polygon_a) {
+ areaAreaContainsPredicates_(polygon_a);
+ transposeMatrix_(m_matrix);
+ }
+
+ private void areaLineDisjointPredicates_(Polygon polygon, Polyline polyline) {
+ m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ m_matrix[MatrixPredicate.InteriorBoundary] = -1;
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ char c = m_scl.charAt(MatrixPredicate.ExteriorInterior);
+ boolean b_has_length = (c != 'T' && c != 'F' ? polyline.calculateLength2D() != 0 : true);
+ m_matrix[MatrixPredicate.ExteriorInterior] = (b_has_length ? 1 : 0);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
+ {
+ boolean has_non_empty_boundary = Boundary.hasNonEmptyBoundary(polyline, null);
+ m_matrix[MatrixPredicate.ExteriorBoundary] = has_non_empty_boundary ? 0 : -1;
+ }
+
+ areaGeomContainsOrDisjointPredicates_(polygon, m_perform_predicates[MatrixPredicate.InteriorExterior] ? MatrixPredicate.InteriorExterior : -1, m_scl.charAt(MatrixPredicate.InteriorExterior), m_perform_predicates[MatrixPredicate.BoundaryExterior] ? MatrixPredicate.BoundaryExterior : -1, m_scl.charAt(MatrixPredicate.BoundaryExterior));
+ }
+
+ private void areaLineContainsPredicates_(Polygon polygon, Polyline polyline) {
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ char c = m_scl.charAt(MatrixPredicate.InteriorInterior);
+ boolean b_has_length = (c != 'T' && c != 'F' ? polyline.calculateLength2D() != 0 : true);
+ m_matrix[MatrixPredicate.InteriorInterior] = (b_has_length ? 1 : 0);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorBoundary])
+ {
+ boolean has_non_empty_boundary = Boundary.hasNonEmptyBoundary(polyline, null);
+ m_matrix[MatrixPredicate.InteriorBoundary] = has_non_empty_boundary ? 0 : -1;
+ }
+
+ m_matrix[MatrixPredicate.InteriorExterior] = 2; //assume polygon has area
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
+ m_matrix[MatrixPredicate.BoundaryExterior] = 1; //assume polygon has area
+ m_matrix[MatrixPredicate.ExteriorInterior] = -1;
+ m_matrix[MatrixPredicate.ExteriorBoundary] = -1;
+ }
+
+ private void areaPointDisjointPredicates_(Polygon polygon) {
+ m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ m_matrix[MatrixPredicate.ExteriorInterior] = 0;
+
+ areaGeomContainsOrDisjointPredicates_(polygon, m_perform_predicates[MatrixPredicate.InteriorExterior] ? MatrixPredicate.InteriorExterior : -1, m_scl.charAt(MatrixPredicate.InteriorExterior), m_perform_predicates[MatrixPredicate.BoundaryExterior] ? MatrixPredicate.BoundaryExterior : -1, m_scl.charAt(MatrixPredicate.BoundaryExterior));
+ }
+
+ private void areaPointContainsPredicates_(Polygon polygon) {
+ m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ m_matrix[MatrixPredicate.InteriorExterior] = 2; //assume polygon has area
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryExterior] = 1; //assume polygon has area
+ m_matrix[MatrixPredicate.ExteriorInterior] = -1;
+ }
+
+ private void lineLineDisjointPredicates_(Polyline polyline_a,
+ Polyline polyline_b) {
+ m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ m_matrix[MatrixPredicate.InteriorBoundary] = -1;
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ char c = m_scl.charAt(MatrixPredicate.InteriorExterior);
+ boolean b_has_length = (c != 'T' && c != 'F' ? polyline_a.calculateLength2D() != 0 : true);
+ m_matrix[MatrixPredicate.InteriorExterior] = (b_has_length ? 1 : 0);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ boolean has_non_empty_boundary_a = Boundary.hasNonEmptyBoundary(polyline_a, null);
+ m_matrix[MatrixPredicate.BoundaryExterior] = has_non_empty_boundary_a ? 0 : -1;
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ char c = m_scl.charAt(MatrixPredicate.ExteriorInterior);
+ boolean b_has_length = (c != 'T' && c != 'F' ? polyline_b.calculateLength2D() != 0 : true);
+ m_matrix[MatrixPredicate.ExteriorInterior] = (b_has_length ? 1 : 0);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
+ {
+ boolean has_non_empty_boundary_b = Boundary.hasNonEmptyBoundary(polyline_b, null);
+ m_matrix[MatrixPredicate.ExteriorBoundary] = has_non_empty_boundary_b ? 0 : -1;
+ }
+ }
+
+ private void linePointDisjointPredicates_(Polyline polyline) {
+ m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ char c = m_scl.charAt(MatrixPredicate.InteriorExterior);
+ boolean b_has_length = (c != 'T' && c != 'F' ? polyline.calculateLength2D() != 0 : true);
+ m_matrix[MatrixPredicate.InteriorExterior] = (b_has_length ? 1 : 0);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ boolean has_non_empty_boundary = Boundary.hasNonEmptyBoundary(polyline, null);
+ m_matrix[MatrixPredicate.BoundaryExterior] = (has_non_empty_boundary ? 0 : -1);
+ }
+
+ m_matrix[MatrixPredicate.ExteriorInterior] = 0;
+ }
+
+ private void pointPointDisjointPredicates_() {
+ m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ m_matrix[MatrixPredicate.InteriorExterior] = 0;
+ m_matrix[MatrixPredicate.ExteriorInterior] = 0;
+ }
+
+ // Invokes the 9 relational predicates of area vs Line.
+ private boolean areaLinePredicates_(int half_edge, int id_a, int id_b) {
+ boolean bRelationKnown = true;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ interiorAreaInteriorLine_(half_edge, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorBoundary])
+ {
+ interiorAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorBoundary);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ interiorAreaExteriorLine_(half_edge, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryInterior])
+ {
+ boundaryAreaInteriorLine_(half_edge, id_a, id_b, m_cluster_index_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryBoundary])
+ {
+ boundaryAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryBoundary);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ boundaryAreaExteriorLine_(half_edge, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ exteriorAreaInteriorLine_(half_edge, id_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
+ {
+ exteriorAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorBoundary);
+ }
+
+ return bRelationKnown;
+ }
+
+ // Invokes the 9 relational predicates of Line vs Line.
+ private boolean lineLinePredicates_(int half_edge, int id_a, int id_b) {
+ boolean bRelationKnown = true;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ interiorLineInteriorLine_(half_edge, id_a, id_b, m_cluster_index_a, m_cluster_index_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorBoundary])
+ {
+ interiorLineBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_a, m_cluster_index_b, MatrixPredicate.InteriorBoundary);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorBoundary);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ interiorLineExteriorLine_(half_edge, id_a, id_b, MatrixPredicate.InteriorExterior);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryInterior])
+ {
+ interiorLineBoundaryLine_(half_edge, id_b, id_a, m_cluster_index_b, m_cluster_index_a, MatrixPredicate.BoundaryInterior);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryBoundary])
+ {
+ boundaryLineBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_a, m_cluster_index_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryBoundary);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ boundaryLineExteriorLine_(half_edge, id_a, id_b, m_cluster_index_a, MatrixPredicate.BoundaryExterior);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ interiorLineExteriorLine_(half_edge, id_b, id_a, MatrixPredicate.ExteriorInterior);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorBoundary])
+ {
+ boundaryLineExteriorLine_(half_edge, id_b, id_a, m_cluster_index_b, MatrixPredicate.ExteriorBoundary);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorBoundary);
+ }
+
+ return bRelationKnown;
+ }
+
+ // Invokes the 9 relational predicates of area vs Point.
+ private boolean areaPointPredicates_(int cluster, int id_a, int id_b) {
+ boolean bRelationKnown = true;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ interiorAreaInteriorPoint_(cluster, id_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ interiorAreaExteriorPoint_(cluster, id_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryInterior])
+ {
+ boundaryAreaInteriorPoint_(cluster, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ boundaryAreaExteriorPoint_(cluster, id_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ exteriorAreaInteriorPoint_(cluster, id_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorInterior);
+ }
+
+ return bRelationKnown;
+ }
+
+ // Invokes the 9 relational predicates of Line vs Point.
+ private boolean linePointPredicates_(int cluster, int id_a, int id_b) {
+ boolean bRelationKnown = true;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ interiorLineInteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ interiorLineExteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryInterior])
+ {
+ boundaryLineInteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ boundaryLineExteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ exteriorLineInteriorPoint_(cluster, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorInterior);
+ }
+
+ return bRelationKnown;
+ }
+
+ // Invokes the 9 relational predicates of Point vs Point.
+ private boolean pointPointPredicates_(int cluster, int id_a, int id_b) {
+ boolean bRelationKnown = true;
+
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ interiorPointInteriorPoint_(cluster, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorInterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ interiorPointExteriorPoint_(cluster, id_a, id_b, MatrixPredicate.InteriorExterior);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorExterior);
+ }
+
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ interiorPointExteriorPoint_(cluster, id_b, id_a, MatrixPredicate.ExteriorInterior);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorInterior);
+ }
+
+ return bRelationKnown;
+ }
+
+ // Relational predicate to determine if the interior of area A intersects
+ // with the interior of area B.
+ private void interiorAreaInteriorArea_(int half_edge, int id_a, int id_b) {
+ if (m_matrix[MatrixPredicate.InteriorInterior] == 2)
+ return;
+
+ int faceParentage = m_topo_graph.getHalfEdgeFaceParentage(half_edge);
+
+ if ((faceParentage & id_a) != 0 && (faceParentage & id_b) != 0)
+ m_matrix[MatrixPredicate.InteriorInterior] = 2;
+ }
+
+ // Relational predicate to determine if the interior of area A intersects
+ // with the boundary of area B.
+ private void interiorAreaBoundaryArea_(int half_edge, int id_a,
+ int predicate) {
+ if (m_matrix[predicate] == 1)
+ return;
+
+ int faceParentage = m_topo_graph.getHalfEdgeFaceParentage(half_edge);
+ int twinFaceParentage = m_topo_graph
+ .getHalfEdgeFaceParentage(m_topo_graph
+ .getHalfEdgeTwin(half_edge));
+
+ if ((faceParentage & id_a) != 0 && (twinFaceParentage & id_a) != 0)
+ m_matrix[predicate] = 1;
+ }
+
+ // Relational predicate to determine if the interior of area A intersects
+ // with the exterior of area B.
+ private void interiorAreaExteriorArea_(int half_edge, int id_a, int id_b,
+ int predicate) {
+ if (m_matrix[predicate] == 2)
+ return;
+
+ int faceParentage = m_topo_graph.getHalfEdgeFaceParentage(half_edge);
+
+ if ((faceParentage & id_a) != 0 && (faceParentage & id_b) == 0)
+ m_matrix[predicate] = 2;
+
+ }
+
+ // Relational predicate to determine if the boundary of area A intersects
+ // with the boundary of area B.
+ private void boundaryAreaBoundaryArea_(int half_edge, int id_a, int id_b) {
+ if (m_matrix[MatrixPredicate.BoundaryBoundary] == 1)
+ return;
+
+ int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);
+
+ if ((parentage & id_a) != 0 && (parentage & id_b) != 0) {
+ m_matrix[MatrixPredicate.BoundaryBoundary] = 1;
+ return;
+ }
+
+ if (m_matrix[MatrixPredicate.BoundaryBoundary] != 0) {
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph
+ .getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0
+ && (clusterParentage & id_b) != 0) {
+ m_matrix[MatrixPredicate.BoundaryBoundary] = 0;
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine if the boundary of area A intersects
+ // with the exterior of area B.
+ private void boundaryAreaExteriorArea_(int half_edge, int id_a, int id_b,
+ int predicate) {
+ if (m_matrix[predicate] == 1)
+ return;
+
+ int faceParentage = m_topo_graph.getHalfEdgeFaceParentage(half_edge);
+ int twinFaceParentage = m_topo_graph
+ .getHalfEdgeFaceParentage(m_topo_graph
+ .getHalfEdgeTwin(half_edge));
+
+ if ((faceParentage & id_b) == 0 && (twinFaceParentage & id_b) == 0)
+ m_matrix[predicate] = 1;
+ }
+
+ // Relational predicate to determine if the interior of area A intersects
+ // with the interior of Line B.
+ private void interiorAreaInteriorLine_(int half_edge, int id_a, int id_b) {
+ if (m_matrix[MatrixPredicate.InteriorInterior] == 1)
+ return;
+
+ int faceParentage = m_topo_graph.getHalfEdgeFaceParentage(half_edge);
+ int twinFaceParentage = m_topo_graph
+ .getHalfEdgeFaceParentage(m_topo_graph
+ .getHalfEdgeTwin(half_edge));
+
+ if ((faceParentage & id_a) != 0 && (twinFaceParentage & id_a) != 0)
+ m_matrix[MatrixPredicate.InteriorInterior] = 1;
+ }
+
+ // Relational predicate to determine if the interior of area A intersects
+ // with the boundary of Line B.
+ private void interiorAreaBoundaryLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_b) {
+ if (m_matrix[MatrixPredicate.InteriorBoundary] == 0)
+ return;
+
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) == 0) {
+ int faceParentage = m_topo_graph
+ .getHalfEdgeFaceParentage(half_edge);
+
+ if ((faceParentage & id_a) != 0) {
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_b);
+
+ if ((clusterParentage & id_b) != 0 && (index % 2 != 0)) {
+ assert (index != -1);
+ m_matrix[MatrixPredicate.InteriorBoundary] = 0;
+ }
+ }
+ }
+ }
+ }
+
+ private void interiorAreaExteriorLine_(int half_edge, int id_a, int id_b)
+ {
+ if (m_matrix[MatrixPredicate.InteriorExterior] == 2)
+ return;
+
+ int half_edge_parentage = m_topo_graph.getHalfEdgeParentage(half_edge);
+
+ if ((half_edge_parentage & id_a) != 0)
+ {//half edge of polygon
+ m_matrix[MatrixPredicate.InteriorExterior] = 2;
+ }
+ }
+
+ // Relational predicate to determine if the boundary of area A intersects
+ // with the interior of Line B.
+ private void boundaryAreaInteriorLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_b) {
+ if (m_matrix[MatrixPredicate.BoundaryInterior] == 1)
+ return;
+
+ int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);
+
+ if ((parentage & id_a) != 0 && (parentage & id_b) != 0) {
+ m_matrix[MatrixPredicate.BoundaryInterior] = 1;
+ return;
+ }
+
+ if (m_matrix[MatrixPredicate.BoundaryInterior] != 0) {
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph
+ .getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0) {
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_b);
+
+ if ((clusterParentage & id_b) != 0 && (index % 2 == 0)) {
+ assert (index != -1);
+ m_matrix[MatrixPredicate.BoundaryInterior] = 0;
+ }
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine if the boundary of area A intersects
+ // with the boundary of Line B.
+ private void boundaryAreaBoundaryLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_b) {
+ if (m_matrix[MatrixPredicate.BoundaryBoundary] == 0)
+ return;
+
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0) {
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_b);
+
+ if ((clusterParentage & id_b) != 0 && (index % 2 != 0)) {
+ assert (index != -1);
+ m_matrix[MatrixPredicate.BoundaryBoundary] = 0;
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine if the boundary of area A intersects
+ // with the exterior of Line B.
+ private void boundaryAreaExteriorLine_(int half_edge, int id_a, int id_b) {
+ if (m_matrix[MatrixPredicate.BoundaryExterior] == 1)
+ return;
+
+ int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);
+
+ if ((parentage & id_a) != 0 && (parentage & id_b) == 0)
+ m_matrix[MatrixPredicate.BoundaryExterior] = 1;
+
+ }
+
+ // Relational predicate to determine if the exterior of area A intersects
+ // with the interior of Line B.
+ private void exteriorAreaInteriorLine_(int half_edge, int id_a) {
+ if (m_matrix[MatrixPredicate.ExteriorInterior] == 1)
+ return;
+
+ int faceParentage = m_topo_graph.getHalfEdgeFaceParentage(half_edge);
+ int twinFaceParentage = m_topo_graph
+ .getHalfEdgeFaceParentage(m_topo_graph
+ .getHalfEdgeTwin(half_edge));
+
+ if ((faceParentage & id_a) == 0 && (twinFaceParentage & id_a) == 0)
+ m_matrix[MatrixPredicate.ExteriorInterior] = 1;
+ }
+
+ // Relational predicate to determine if the exterior of area A intersects
+ // with the boundary of Line B.
+ private void exteriorAreaBoundaryLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_b) {
+ if (m_matrix[MatrixPredicate.ExteriorBoundary] == 0)
+ return;
+
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) == 0) {
+ int faceParentage = m_topo_graph
+ .getHalfEdgeFaceParentage(half_edge);
+
+ if ((faceParentage & id_a) == 0) {
+ assert ((m_topo_graph.getHalfEdgeParentage(m_topo_graph
+ .getHalfEdgeTwin(half_edge)) & id_a) == 0);
+
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_b);
+
+ if ((clusterParentage & id_b) != 0 && (index % 2 != 0)) {
+ assert (index != -1);
+ m_matrix[MatrixPredicate.ExteriorBoundary] = 0;
+ }
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine if the interior of Line A intersects
+ // with the interior of Line B.
+ private void interiorLineInteriorLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_a, int cluster_index_b) {
+ if (m_matrix[MatrixPredicate.InteriorInterior] == 1)
+ return;
+
+ int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);
+
+ if ((parentage & id_a) != 0 && (parentage & id_b) != 0) {
+ m_matrix[MatrixPredicate.InteriorInterior] = 1;
+ return;
+ }
+
+ if (m_matrix[MatrixPredicate.InteriorInterior] != 0) {
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph
+ .getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0
+ && (clusterParentage & id_b) != 0) {
+ int index_a = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_a);
+ int index_b = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_b);
+ assert (index_a != -1);
+ assert (index_b != -1);
+
+ if ((index_a % 2 == 0) && (index_b % 2 == 0)) {
+ assert ((m_topo_graph.getClusterParentage(cluster) & id_a) != 0 && (m_topo_graph
+ .getClusterParentage(cluster) & id_b) != 0);
+ m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ }
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine of the interior of LineA intersects
+ // with the boundary of Line B.
+ private void interiorLineBoundaryLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_a, int cluster_index_b, int predicate) {
+ if (m_matrix[predicate] == 0)
+ return;
+
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0
+ && (clusterParentage & id_b) != 0) {
+ int index_a = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_a);
+ int index_b = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_b);
+ assert (index_a != -1);
+ assert (index_b != -1);
+
+ if ((index_a % 2 == 0) && (index_b % 2 != 0)) {
+ assert ((m_topo_graph.getClusterParentage(cluster) & id_a) != 0 && (m_topo_graph
+ .getClusterParentage(cluster) & id_b) != 0);
+ m_matrix[predicate] = 0;
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine if the interior of Line A intersects
+ // with the exterior of Line B.
+ private void interiorLineExteriorLine_(int half_edge, int id_a, int id_b,
+ int predicate) {
+ if (m_matrix[predicate] == 1)
+ return;
+
+ int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);
+
+ if ((parentage & id_a) != 0 && (parentage & id_b) == 0)
+ m_matrix[predicate] = 1;
+ }
+
+ // Relational predicate to determine if the boundary of Line A intersects
+ // with the boundary of Line B.
+ private void boundaryLineBoundaryLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_a, int cluster_index_b) {
+ if (m_matrix[MatrixPredicate.BoundaryBoundary] == 0)
+ return;
+
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0
+ && (clusterParentage & id_b) != 0) {
+ int index_a = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_a);
+ int index_b = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_b);
+ assert (index_a != -1);
+ assert (index_b != -1);
+
+ if ((index_a % 2 != 0) && (index_b % 2 != 0)) {
+ assert ((m_topo_graph.getClusterParentage(cluster) & id_a) != 0 && (m_topo_graph
+ .getClusterParentage(cluster) & id_b) != 0);
+ m_matrix[MatrixPredicate.BoundaryBoundary] = 0;
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine if the boundary of Line A intersects
+ // with the exterior of Line B.
+ private void boundaryLineExteriorLine_(int half_edge, int id_a, int id_b,
+ int cluster_index_a, int predicate) {
+ if (m_matrix[predicate] == 0)
+ return;
+
+ if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
+ .getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
+ m_visited_index) != 1) {
+ int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_b) == 0) {
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_a);
+ assert (index != -1);
+
+ if (index % 2 != 0) {
+ assert ((m_topo_graph.getClusterParentage(cluster) & id_a) != 0);
+ m_matrix[predicate] = 0;
+ }
+ }
+ }
+ }
+
+ // Relational predicate to determine if the interior of area A intersects
+ // with the interior of Point B.
+ private void interiorAreaInteriorPoint_(int cluster, int id_a) {
+ if (m_matrix[MatrixPredicate.InteriorInterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) == 0) {
+ int chain = m_topo_graph.getClusterChain(cluster);
+ int chainParentage = m_topo_graph.getChainParentage(chain);
+
+ if ((chainParentage & id_a) != 0) {
+ m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ }
+ }
+ }
+
+ private void interiorAreaExteriorPoint_(int cluster, int id_a)
+ {
+ if (m_matrix[MatrixPredicate.InteriorExterior] == 2)
+ return;
+
+ int cluster_parentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((cluster_parentage & id_a) != 0)
+ {
+ m_matrix[MatrixPredicate.InteriorExterior] = 2;
+ }
+ }
+
+ // Relational predicate to determine if the boundary of area A intersects
+ // with the interior of Point B.
+ private void boundaryAreaInteriorPoint_(int cluster, int id_a, int id_b) {
+ if (m_matrix[MatrixPredicate.BoundaryInterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0 && (clusterParentage & id_b) != 0) {
+ m_matrix[MatrixPredicate.BoundaryInterior] = 0;
+ }
+ }
+
+ private void boundaryAreaExteriorPoint_(int cluster, int id_a)
+ {
+ if (m_matrix[MatrixPredicate.BoundaryExterior] == 1)
+ return;
+
+ int cluster_parentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((cluster_parentage & id_a) != 0)
+ {
+ m_matrix[MatrixPredicate.BoundaryExterior] = 1;
+ }
+ }
+
+ // Relational predicate to determine if the exterior of area A intersects
+ // with the interior of Point B.
+ private void exteriorAreaInteriorPoint_(int cluster, int id_a) {
+ if (m_matrix[MatrixPredicate.ExteriorInterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) == 0) {
+ int chain = m_topo_graph.getClusterChain(cluster);
+ int chainParentage = m_topo_graph.getChainParentage(chain);
+
+ if ((chainParentage & id_a) == 0) {
+ m_matrix[MatrixPredicate.ExteriorInterior] = 0;
+ }
+ }
+ }
+
+ // Relational predicate to determine if the interior of Line A intersects
+ // with the interior of Point B.
+ private void interiorLineInteriorPoint_(int cluster, int id_a, int id_b,
+ int cluster_index_a) {
+ if (m_matrix[MatrixPredicate.InteriorInterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0 && (clusterParentage & id_b) != 0) {
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_a);
+
+ if (index % 2 == 0) {
+ m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ }
+ }
+ }
+
+ private void interiorLineExteriorPoint_(int cluster, int id_a, int id_b, int cluster_index_a)
+ {
+ if (m_matrix[MatrixPredicate.InteriorExterior] == 1)
+ return;
+
+ int half_edge_a = m_topo_graph.getClusterHalfEdge(cluster);
+
+ if (half_edge_a != -1)
+ {
+ m_matrix[MatrixPredicate.InteriorExterior] = 1;
+ return;
+ }
+
+ if (m_matrix[MatrixPredicate.InteriorExterior] != 0)
+ {
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_b) == 0)
+ {
+ assert(m_topo_graph.getClusterUserIndex(cluster, cluster_index_a) % 2 == 0);
+ m_matrix[MatrixPredicate.InteriorExterior] = 0;
+ return;
+ }
+ }
+
+ return;
+ }
+
+ // Relational predicate to determine if the boundary of Line A intersects
+ // with the interior of Point B.
+ private void boundaryLineInteriorPoint_(int cluster, int id_a, int id_b,
+ int cluster_index_a) {
+ if (m_matrix[MatrixPredicate.BoundaryInterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0 && (clusterParentage & id_b) != 0) {
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_a);
+
+ if (index % 2 != 0) {
+ m_matrix[MatrixPredicate.BoundaryInterior] = 0;
+ }
+ }
+ }
+
+ // Relational predicate to determine if the boundary of Line A intersects
+ // with the exterior of Point B.
+ private void boundaryLineExteriorPoint_(int cluster, int id_a, int id_b,
+ int cluster_index_a) {
+ if (m_matrix[MatrixPredicate.BoundaryExterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0 && (clusterParentage & id_b) == 0) {
+ int index = m_topo_graph.getClusterUserIndex(cluster,
+ cluster_index_a);
+
+ if (index % 2 != 0) {
+ m_matrix[MatrixPredicate.BoundaryExterior] = 0;
+ }
+ }
+ }
+
+ // Relational predicate to determine if the exterior of Line A intersects
+ // with the interior of Point B.
+ private void exteriorLineInteriorPoint_(int cluster, int id_a, int id_b) {
+ if (m_matrix[MatrixPredicate.ExteriorInterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) == 0 && (clusterParentage & id_b) != 0) {
+ m_matrix[MatrixPredicate.ExteriorInterior] = 0;
+ }
+ }
+
+ // Relational predicate to determine if the interior of Point A intersects
+ // with the interior of Point B.
+ private void interiorPointInteriorPoint_(int cluster, int id_a, int id_b) {
+ if (m_matrix[MatrixPredicate.InteriorInterior] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0 && (clusterParentage & id_b) != 0) {
+ m_matrix[MatrixPredicate.InteriorInterior] = 0;
+ }
+ }
+
+ // Relational predicate to determine if the interior of Point A intersects
+ // with the exterior of Point B.
+ private void interiorPointExteriorPoint_(int cluster, int id_a, int id_b,
+ int predicate) {
+ if (m_matrix[predicate] == 0)
+ return;
+
+ int clusterParentage = m_topo_graph.getClusterParentage(cluster);
+
+ if ((clusterParentage & id_a) != 0 && (clusterParentage & id_b) == 0) {
+ m_matrix[predicate] = 0;
+ }
+ }
+
+ // Computes the 9 intersection relationships of boundary, interior, and
+ // exterior of geometry_a vs geometry_b using the Topo_graph for area/area,
+ // area/Line, and Line/Line relations
+ private void computeMatrixTopoGraphHalfEdges_(int geometry_a, int geometry_b) {
+ boolean bRelationKnown = false;
+
+ int id_a = m_topo_graph.getGeometryID(geometry_a);
+ int id_b = m_topo_graph.getGeometryID(geometry_b);
+
+ m_visited_index = m_topo_graph.createUserIndexForHalfEdges();
+
+ for (int cluster = m_topo_graph.getFirstCluster(); cluster != -1; cluster = m_topo_graph
+ .getNextCluster(cluster)) {
+ int first_half_edge = m_topo_graph.getClusterHalfEdge(cluster);
+ if (first_half_edge == -1)
+ {
+ if (m_predicates_cluster != -1)
+ {
+ // Treat cluster as an interior point
+ switch (m_predicates_cluster)
+ {
+ case Predicates.AreaPointPredicates:
+ bRelationKnown = areaPointPredicates_(cluster, id_a, id_b);
+ break;
+ case Predicates.LinePointPredicates:
+ bRelationKnown = linePointPredicates_(cluster, id_a, id_b);
+ break;
+ default:
+ throw GeometryException.GeometryInternalError();
+ }
+ }
+
+ continue;
+ }
+
+ int next_half_edge = first_half_edge;
+
+ do {
+ int half_edge = next_half_edge;
+ int visited = m_topo_graph.getHalfEdgeUserIndex(half_edge,
+ m_visited_index);
+
+ if (visited != 1) {
+ do {
+ // Invoke relational predicates
+ switch (m_predicates_half_edge) {
+ case Predicates.AreaAreaPredicates:
+ bRelationKnown = areaAreaPredicates_(half_edge,
+ id_a, id_b);
+ break;
+ case Predicates.AreaLinePredicates:
+ bRelationKnown = areaLinePredicates_(half_edge,
+ id_a, id_b);
+ break;
+ case Predicates.LineLinePredicates:
+ bRelationKnown = lineLinePredicates_(half_edge,
+ id_a, id_b);
+ break;
+ default:
+ throw GeometryException.GeometryInternalError();
+ }
+
+ if (bRelationKnown)
+ break;
+
+ m_topo_graph.setHalfEdgeUserIndex(half_edge,
+ m_visited_index, 1);
+ half_edge = m_topo_graph.getHalfEdgeNext(half_edge);
+ } while (half_edge != next_half_edge && !bRelationKnown);
+ }
+
+ if (bRelationKnown)
+ break;
+
+ next_half_edge = m_topo_graph.getHalfEdgeNext(m_topo_graph
+ .getHalfEdgeTwin(half_edge));
+ } while (next_half_edge != first_half_edge);
+
+ if (bRelationKnown)
+ break;
+ }
+
+ if (!bRelationKnown)
+ setRemainingPredicatesToFalse_();
+
+ m_topo_graph.deleteUserIndexForHalfEdges(m_visited_index);
+ }
+
+ // Computes the 9 intersection relationships of boundary, interior, and
+ // exterior of geometry_a vs geometry_b using the Topo_graph for area/Point,
+ // Line/Point, and Point/Point relations
+ private void computeMatrixTopoGraphClusters_(int geometry_a, int geometry_b) {
+ boolean bRelationKnown = false;
+
+ int id_a = m_topo_graph.getGeometryID(geometry_a);
+ int id_b = m_topo_graph.getGeometryID(geometry_b);
+
+ for (int cluster = m_topo_graph.getFirstCluster(); cluster != -1; cluster = m_topo_graph
+ .getNextCluster(cluster)) {
+ // Invoke relational predicates
+ switch (m_predicates_cluster) {
+ case Predicates.AreaPointPredicates:
+ bRelationKnown = areaPointPredicates_(cluster, id_a, id_b);
+ break;
+ case Predicates.LinePointPredicates:
+ bRelationKnown = linePointPredicates_(cluster, id_a, id_b);
+ break;
+ case Predicates.PointPointPredicates:
+ bRelationKnown = pointPointPredicates_(cluster, id_a, id_b);
+ break;
+ default:
+ throw GeometryException.GeometryInternalError();
+ }
+
+ if (bRelationKnown)
+ break;
+ }
+
+ if (!bRelationKnown)
+ setRemainingPredicatesToFalse_();
+ }
+
+ // Call this method to set the edit shape, if the edit shape has been
+ // cracked and clustered already.
+ private void setEditShape_(EditShape shape, ProgressTracker progressTracker) {
+ m_topo_graph.setEditShape(shape, progressTracker);
+ }
+
+ private void setEditShapeCrackAndCluster_(EditShape shape,
+ double tolerance, ProgressTracker progress_tracker) {
+ editShapeCrackAndCluster_(shape, tolerance, progress_tracker);
+ setEditShape_(shape, progress_tracker);
+ }
+
+ private void editShapeCrackAndCluster_(EditShape shape, double tolerance,
+ ProgressTracker progress_tracker) {
+ CrackAndCluster.execute(shape, tolerance, progress_tracker, false); //do not filter degenerate segments.
+ shape.filterClosePoints(0, true, true);//remove degeneracies from polygon geometries.
+ for (int geometry = shape.getFirstGeometry(); geometry != -1; geometry = shape
+ .getNextGeometry(geometry)) {
+ if (shape.getGeometryType(geometry) == Geometry.Type.Polygon
+ .value())
+ Simplificator.execute(shape, geometry, -1, false, progress_tracker);
+ }
+ }
+
+ // Upgrades the geometry to a feature geometry.
+ private static Geometry convertGeometry_(Geometry geometry, double tolerance) {
+ int gt = geometry.getType().value();
+
+ if (Geometry.isSegment(gt)) {
+ Polyline polyline = new Polyline(geometry.getDescription());
+ polyline.addSegment((Segment) geometry, true);
+ return polyline;
+ }
+
+ if (gt == Geometry.GeometryType.Envelope) {
+ Envelope envelope = (Envelope) (geometry);
+ Envelope2D env = new Envelope2D();
+ geometry.queryEnvelope2D(env);
+
+ if (env.getHeight() <= tolerance && env.getWidth() <= tolerance) {// treat
+ // as
+ // point
+ Point point = new Point(geometry.getDescription());
+ envelope.getCenter(point);
+ return point;
+ }
+
+ if (env.getHeight() <= tolerance || env.getWidth() <= tolerance) {// treat
+ // as
+ // line
+ Polyline polyline = new Polyline(geometry.getDescription());
+ Point p = new Point();
+ envelope.queryCornerByVal(0, p);
+ polyline.startPath(p);
+ envelope.queryCornerByVal(2, p);
+ polyline.lineTo(p);
+ return polyline;
+ }
+
+ // treat as polygon
+ Polygon polygon = new Polygon(geometry.getDescription());
+ polygon.addEnvelope(envelope, false);
+ return polygon;
+ }
+
+ return geometry;
+ }
+}
diff --git a/src/com/esri/core/geometry/RingOrientationFixer.java b/src/main/java/com/esri/core/geometry/RingOrientationFixer.java
similarity index 74%
rename from src/com/esri/core/geometry/RingOrientationFixer.java
rename to src/main/java/com/esri/core/geometry/RingOrientationFixer.java
index 21ed6606..84fa66b5 100644
--- a/src/com/esri/core/geometry/RingOrientationFixer.java
+++ b/src/main/java/com/esri/core/geometry/RingOrientationFixer.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ class RingOrientationFixer {
int m_node_2_user_index;
int m_path_orientation_index;
int m_path_parentage_index;
+ boolean m_fixSelfTangency;
static final class Edges {
EditShape m_shape;
@@ -221,6 +222,11 @@ void reset() {
}
boolean fixRingOrientation_() {
+ boolean bFound = false;
+
+ if (m_fixSelfTangency)
+ bFound = fixRingSelfTangency_();
+
if (m_shape.getPathCount(m_geometry) == 1) {
int path = m_shape.getFirstPath(m_geometry);
double area = m_shape.getRingArea(path);
@@ -257,7 +263,6 @@ boolean fixRingOrientation_() {
}
AttributeStreamOfInt32 bunch = new AttributeStreamOfInt32(0);
- boolean bFound = false;
m_y_scanline = NumberUtils.TheNaN;
Point2D pt = new Point2D();
m_unknown_ring_orientation_count = m_shape.getPathCount(m_geometry);
@@ -518,12 +523,163 @@ boolean insertEdge_(int vertex, int reused_node) {
}
static boolean execute(EditShape shape, int geometry,
- IndexMultiDCList sorted_vertices) {
+ IndexMultiDCList sorted_vertices, boolean fixSelfTangency) {
RingOrientationFixer fixer = new RingOrientationFixer();
fixer.m_shape = shape;
fixer.m_geometry = geometry;
fixer.m_sorted_vertices = sorted_vertices;
+ fixer.m_fixSelfTangency = fixSelfTangency;
return fixer.fixRingOrientation_();
}
+ boolean fixRingSelfTangency_() {
+ AttributeStreamOfInt32 self_tangent_paths = new AttributeStreamOfInt32(
+ 0);
+ AttributeStreamOfInt32 self_tangency_clusters = new AttributeStreamOfInt32(
+ 0);
+ int tangent_path_first_vertex_index = -1;
+ int tangent_vertex_cluster_index = -1;
+ Point2D pt_prev = new Point2D();
+ pt_prev.setNaN();
+ int prev_vertex = -1;
+ int old_path = -1;
+ int current_cluster = -1;
+ Point2D pt = new Point2D();
+ for (int ivertex = m_sorted_vertices.getFirst(m_sorted_vertices
+ .getFirstList()); ivertex != -1; ivertex = m_sorted_vertices
+ .getNext(ivertex)) {
+ int vertex = m_sorted_vertices.getData(ivertex);
+ m_shape.getXY(vertex, pt);
+ int path = m_shape.getPathFromVertex(vertex);
+ if (pt_prev.isEqual(pt) && old_path == path) {
+ if (tangent_vertex_cluster_index == -1) {
+ tangent_path_first_vertex_index = m_shape
+ .createPathUserIndex();
+ tangent_vertex_cluster_index = m_shape.createUserIndex();
+ }
+
+ if (current_cluster == -1) {
+ current_cluster = self_tangency_clusters.size();
+ m_shape.setUserIndex(prev_vertex,
+ tangent_vertex_cluster_index, current_cluster);
+ self_tangency_clusters.add(1);
+ int p = m_shape.getPathUserIndex(path,
+ tangent_path_first_vertex_index);
+ if (p == -1) {
+ m_shape.setPathUserIndex(path,
+ tangent_path_first_vertex_index, prev_vertex);
+ self_tangent_paths.add(path);
+ }
+ }
+
+ m_shape.setUserIndex(vertex, tangent_vertex_cluster_index,
+ current_cluster);
+ self_tangency_clusters
+ .setLast(self_tangency_clusters.getLast() + 1);
+ } else {
+ current_cluster = -1;
+ pt_prev.setCoords(pt);
+ }
+
+ prev_vertex = vertex;
+ old_path = path;
+ }
+
+ if (self_tangent_paths.size() == 0)
+ return false;
+
+ // Now self_tangent_paths contains list of clusters of tangency for each
+ // path.
+ // The clusters contains list of clusters and for each cluster it
+ // contains a list of vertices.
+ AttributeStreamOfInt32 vertex_stack = new AttributeStreamOfInt32(0);
+ AttributeStreamOfInt32 cluster_stack = new AttributeStreamOfInt32(0);
+
+ for (int ipath = 0, npath = self_tangent_paths.size(); ipath < npath; ipath++) {
+ int path = self_tangent_paths.get(ipath);
+ int first_vertex = m_shape.getPathUserIndex(path,
+ tangent_path_first_vertex_index);
+ int cluster = m_shape.getUserIndex(first_vertex,
+ tangent_vertex_cluster_index);
+ vertex_stack.clear(false);
+ cluster_stack.clear(false);
+ vertex_stack.add(first_vertex);
+ cluster_stack.add(cluster);
+
+ for (int vertex = m_shape.getNextVertex(first_vertex); vertex != first_vertex; vertex = m_shape
+ .getNextVertex(vertex)) {
+ int vertex_to = vertex;
+ int cluster_to = m_shape.getUserIndex(vertex_to,
+ tangent_vertex_cluster_index);
+ if (cluster_to != -1) {
+ if (cluster_stack.size() == 0) {
+ cluster_stack.add(cluster_to);
+ vertex_stack.add(vertex_to);
+ continue;
+ }
+
+ if (cluster_stack.getLast() == cluster_to) {
+ int vertex_from = vertex_stack.getLast();
+
+ // peel the loop from path
+ int from_next = m_shape.getNextVertex(vertex_from);
+ int from_prev = m_shape.getPrevVertex(vertex_from);
+ int to_next = m_shape.getNextVertex(vertex_to);
+ int to_prev = m_shape.getPrevVertex(vertex_to);
+
+ m_shape.setNextVertex_(vertex_from, to_next);
+ m_shape.setPrevVertex_(to_next, vertex_from);
+
+ m_shape.setNextVertex_(vertex_to, from_next);
+ m_shape.setPrevVertex_(from_next, vertex_to);
+
+ // vertex_from is left in the path we are processing,
+ // while the vertex_to is in the loop being teared off.
+ boolean[] first_vertex_correction_requied = new boolean[] { false };
+ int new_path = m_shape.insertClosedPath_(m_geometry,
+ -1, from_next, m_shape.getFirstVertex(path),
+ first_vertex_correction_requied);
+
+ m_shape.setUserIndex(vertex,
+ tangent_vertex_cluster_index, -1);
+
+ // Fix the path after peeling if the peeled loop had the
+ // first path vertex in it
+
+ if (first_vertex_correction_requied[0]) {
+ m_shape.setFirstVertex_(path, to_next);
+ }
+
+ int path_size = m_shape.getPathSize(path);
+ int new_path_size = m_shape.getPathSize(new_path);
+ path_size -= new_path_size;
+ assert (path_size >= 3);
+ m_shape.setPathSize_(path, path_size);
+
+ self_tangency_clusters.set(cluster_to,
+ self_tangency_clusters.get(cluster_to) - 1);
+ if (self_tangency_clusters.get(cluster_to) == 1) {
+ self_tangency_clusters.set(cluster_to, 0);
+ cluster_stack.removeLast();
+ vertex_stack.removeLast();
+ } else {
+ // this cluster has more than two vertices in it.
+ }
+
+ first_vertex = vertex_from;// reset the counter to
+ // ensure we find all loops.
+ vertex = vertex_from;
+ } else {
+ vertex_stack.add(vertex);
+ cluster_stack.add(cluster_to);
+ }
+ }
+ }
+ }
+
+ m_shape.removePathUserIndex(tangent_path_first_vertex_index);
+ m_shape.removeUserIndex(tangent_vertex_cluster_index);
+ return true;
+ }
+
}
diff --git a/src/com/esri/core/geometry/Segment.java b/src/main/java/com/esri/core/geometry/Segment.java
similarity index 83%
rename from src/com/esri/core/geometry/Segment.java
rename to src/main/java/com/esri/core/geometry/Segment.java
index 501f7dda..b15364a2 100644
--- a/src/com/esri/core/geometry/Segment.java
+++ b/src/main/java/com/esri/core/geometry/Segment.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,16 +25,13 @@
package com.esri.core.geometry;
import com.esri.core.geometry.VertexDescription.Semantics;
+
import java.io.Serializable;
/**
* A base class for segments. Presently only Line segments are supported.
*/
public abstract class Segment extends Geometry implements Serializable {
-
- // UPDATED PORT TO MATCH NATIVE AS OF JAN 30 2011
- private static final long serialVersionUID = 1L;
-
double m_xStart;
double m_yStart;
@@ -49,11 +46,11 @@ public abstract class Segment extends Geometry implements Serializable {
/**
* Returns XY coordinates of the start point.
*/
- Point2D getStartXY() {
+ public Point2D getStartXY() {
return Point2D.construct(m_xStart, m_yStart);
}
- void getStartXY(Point2D pt) {
+ public void getStartXY(Point2D pt) {
pt.x = m_xStart;
pt.y = m_yStart;
}
@@ -61,29 +58,29 @@ void getStartXY(Point2D pt) {
/**
* Sets the XY coordinates of the start point.
*/
- void setStartXY(Point2D pt) {
+ public void setStartXY(Point2D pt) {
_setXY(0, pt);
}
- void setStartXY(double x, double y) {
+ public void setStartXY(double x, double y) {
_setXY(0, Point2D.construct(x, y));
}
/**
* Returns XYZ coordinates of the start point. Z if 0 if Z is missing.
*/
- Point3D getStartXYZ() {
+ public Point3D getStartXYZ() {
return _getXYZ(0);
}
/**
* Sets the XYZ coordinates of the start point.
*/
- void setStartXYZ(Point3D pt) {
+ public void setStartXYZ(Point3D pt) {
_setXYZ(0, pt);
}
- void setStartXYZ(double x, double y, double z) {
+ public void setStartXYZ(double x, double y, double z) {
_setXYZ(0, Point3D.construct(x, y, z));
}
@@ -193,11 +190,11 @@ public double getEndY() {
*
* @return The XY coordinates of the end point.
*/
- Point2D getEndXY() {
+ public Point2D getEndXY() {
return Point2D.construct(m_xEnd, m_yEnd);
}
- void getEndXY(Point2D pt) {
+ public void getEndXY(Point2D pt) {
pt.x = m_xEnd;
pt.y = m_yEnd;
}
@@ -208,11 +205,11 @@ void getEndXY(Point2D pt) {
* @param pt
* The end point of the segment.
*/
- void setEndXY(Point2D pt) {
+ public void setEndXY(Point2D pt) {
_setXY(1, pt);
}
- void setEndXY(double x, double y) {
+ public void setEndXY(double x, double y) {
_setXY(1, Point2D.construct(x, y));
}
@@ -221,18 +218,18 @@ void setEndXY(double x, double y) {
*
* @return The XYZ coordinates of the end point.
*/
- Point3D getEndXYZ() {
+ public Point3D getEndXYZ() {
return _getXYZ(1);
}
/**
* Sets the XYZ coordinates of the end point.
*/
- void setEndXYZ(Point3D pt) {
+ public void setEndXYZ(Point3D pt) {
_setXYZ(1, pt);
}
- void setEndXYZ(double x, double y, double z) {
+ public void setEndXYZ(double x, double y, double z) {
_setXYZ(1, Point3D.construct(x, y, z));
}
@@ -358,7 +355,7 @@ int intersect(Segment other, Point2D[] intersectionPoints,
* Returns TRUE if this segment intersects with the other segment with the
* given tolerance.
*/
- boolean isIntersecting(Segment other, double tolerance) {
+ public boolean isIntersecting(Segment other, double tolerance) {
return _isIntersecting(other, tolerance, false) != 0;
}
@@ -366,7 +363,7 @@ boolean isIntersecting(Segment other, double tolerance) {
* Returns TRUE if the point and segment intersect (not disjoint) for the
* given tolerance.
*/
- boolean isIntersecting(Point2D pt, double tolerance) {
+ public boolean isIntersecting(Point2D pt, double tolerance) {
return _isIntersectingPoint(pt, tolerance, false);
}
@@ -439,7 +436,7 @@ private Point3D _getXYZ(int endPoint) {
}
if (m_description.hasZ())
- pt.z = m_attributes[_getEndPointOffset(endPoint)];
+ pt.z = m_attributes[_getEndPointOffset(m_description, endPoint)];
else
pt.z = VertexDescription.getDefaultValue(Semantics.Z);
@@ -472,79 +469,64 @@ private void _setXYZ(int endPoint, Point3D pt) {
}
if (bHasZ)
- m_attributes[_getEndPointOffset(endPoint)] = pt.z;
+ m_attributes[_getEndPointOffset(m_description, endPoint)] = pt.z;
}
@Override
- void _beforeDropAttributeImpl(int semantics) {
- _touch();
- if (isEmptyImpl())
+ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
+ if (m_attributes == null) {
+ m_description = newDescription;
return;
-
- // _ASSERT(semantics != enum_value2(VertexDescription, Semantics,
- // POSITION));
- int attributeIndex = m_description.getAttributeIndex(semantics);
- int offset = m_description._getPointAttributeOffset(attributeIndex) - 2;
- int comps = VertexDescription.getComponentCount(semantics);
- int totalCompsOld = m_description._getTotalComponents() - 2;
- if (totalCompsOld > comps) {
- int offset0 = _getEndPointOffset(0);
- for (int i = offset + comps; i < totalCompsOld * 2; i++)
- m_attributes[offset0 + i - comps] = m_attributes[offset0 + i];
-
- int offset1 = _getEndPointOffset(1) - comps; // -comp is for deleted
- // attribute of
- // start vertex
- for (int i = offset + comps; i < totalCompsOld; i++)
- m_attributes[offset1 + i - comps] = m_attributes[offset1 + i];
- }
- }
-
- @Override
- void _afterAddAttributeImpl(int semantics) {
- _touch();
- int attributeIndex = m_description.getAttributeIndex(semantics);
- int offset = m_description._getPointAttributeOffset(attributeIndex) - 2;
- int comps = VertexDescription.getComponentCount(semantics);
- int totalComps = m_description._getTotalComponents() - 2;
- _resizeAttributes(totalComps);
- int totalCompsOld = totalComps - comps; // the total number of
- // components before resize.
-
- int offset0 = _getEndPointOffset(0);
- int offset1 = _getEndPointOffset(1);
- int offset1old = offset1 - comps;
- for (int i = totalCompsOld - 1; i >= 0; i--) {// correct the position of
- // the End attributes
- m_attributes[offset1 + i] = m_attributes[offset1old + i];
- }
-
- // move attributes for start end end points that go after the insertion
- // point
- for (int i = totalComps - 1; i >= offset + comps; i--) {
- m_attributes[offset0 + i] = m_attributes[offset0 + i - comps];
- m_attributes[offset1 + i] = m_attributes[offset1 + i - comps];
}
-
- // initialize added attribute to the default value.
- double dv = VertexDescription.getDefaultValue(semantics);
- for (int i = 0; i < comps; i++) {
- m_attributes[offset0 + offset + i] = dv;
- m_attributes[offset1 + offset + i] = dv;
+
+ int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);
+
+ double[] newAttributes = new double[(newDescription.getTotalComponentCount() - 2) * 2];
+
+ int old_offset0 = _getEndPointOffset(m_description, 0);
+ int old_offset1 = _getEndPointOffset(m_description, 1);
+
+ int new_offset0 = _getEndPointOffset(newDescription, 0);
+ int new_offset1 = _getEndPointOffset(newDescription, 1);
+
+ int j = 0;
+ for (int i = 1, n = newDescription.getAttributeCount(); i < n; i++) {
+ int semantics = newDescription.getSemantics(i);
+ int nords = VertexDescription.getComponentCount(semantics);
+ if (mapping[i] == -1)
+ {
+ double d = VertexDescription.getDefaultValue(semantics);
+ for (int ord = 0; ord < nords; ord++)
+ {
+ newAttributes[new_offset0 + j] = d;
+ newAttributes[new_offset1 + j] = d;
+ j++;
+ }
+ }
+ else {
+ int m = mapping[i];
+ int offset = m_description._getPointAttributeOffset(m) - 2;
+ for (int ord = 0; ord < nords; ord++)
+ {
+ newAttributes[new_offset0 + j] = m_attributes[old_offset0 + offset];
+ newAttributes[new_offset1 + j] = m_attributes[old_offset1 + offset];
+ j++;
+ offset++;
+ }
+ }
+
}
+
+ m_attributes = newAttributes;
+ m_description = newDescription;
}
private void _get(int endPoint, Point outPoint) {
if (isEmptyImpl())
throw new GeometryException("empty geometry");// ._setToDefault();
- // FIXME Native has this line repeated twice! Check up on this.
outPoint.assignVertexDescription(m_description);
- // outPoint.assignVertexDescription(m_description);
-
- if (outPoint.isEmptyImpl())
- outPoint._setToDefault();
for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
@@ -576,7 +558,6 @@ private void _set(int endPoint, Point src) {
}
double _getAttributeAsDbl(int endPoint, int semantics, int ordinate) {
- // FIXME review rohits impl. Only an assertion in native
if (isEmptyImpl())
throw new GeometryException(
"This operation was performed on an Empty Geometry.");
@@ -596,9 +577,9 @@ private void _set(int endPoint, Point src) {
int attributeIndex = m_description.getAttributeIndex(semantics);
if (attributeIndex >= 0) {
if (m_attributes != null)
- _resizeAttributes(m_description._getTotalComponents() - 2);
+ _resizeAttributes(m_description.getTotalComponentCount() - 2);
- return m_attributes[_getEndPointOffset(endPoint)
+ return m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex)
- 2 + ordinate];
} else
@@ -625,11 +606,12 @@ void _setAttribute(int endPoint, int semantics, int ordinate, double value) {
}
if (semantics == Semantics.POSITION) {
- if (endPoint != 0)
+ if (endPoint != 0) {
if (ordinate != 0)
m_yEnd = value;
else
m_xEnd = value;
+ }
else if (ordinate != 0)
m_yStart = value;
else
@@ -637,10 +619,10 @@ else if (ordinate != 0)
return;
}
- if (m_attributes != null)
- _resizeAttributes(m_description._getTotalComponents() - 2);
+ if (m_attributes == null)
+ _resizeAttributes(m_description.getTotalComponentCount() - 2);
- m_attributes[_getEndPointOffset(endPoint)
+ m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex) - 2
+ ordinate] = value;
@@ -657,9 +639,9 @@ public void copyTo(Geometry dst) {
Segment segDst = (Segment) dst;
segDst.m_description = m_description;
- segDst._resizeAttributes(m_description._getTotalComponents() - 2);
+ segDst._resizeAttributes(m_description.getTotalComponentCount() - 2);
_attributeCopy(m_attributes, 0, segDst.m_attributes, 0,
- (m_description._getTotalComponents() - 2) * 2);
+ (m_description.getTotalComponentCount() - 2) * 2);
segDst.m_xStart = m_xStart;
segDst.m_yStart = m_yStart;
segDst.m_xEnd = m_xEnd;
@@ -703,13 +685,27 @@ boolean _equalsImpl(Segment other) {
if (m_xStart != other.m_xStart || m_xEnd != other.m_xEnd
|| m_yStart != other.m_yStart || m_yEnd != other.m_yEnd)
return false;
- for (int i = 0; i < (m_description._getTotalComponents() - 2) * 2; i++)
- if (m_attributes[i] != other.m_attributes[i])
+ for (int i = 0; i < (m_description.getTotalComponentCount() - 2) * 2; i++)
+ if (!NumberUtils.isEqualNonIEEE(m_attributes[i], other.m_attributes[i]))
return false;
return true;
}
+ @Override
+ public int hashCode() {
+ int hash = m_description.hashCode();
+ hash = NumberUtils.hash(hash, m_xStart);
+ hash = NumberUtils.hash(hash, m_yStart);
+ hash = NumberUtils.hash(hash, m_xEnd);
+ hash = NumberUtils.hash(hash, m_yEnd);
+ for (int i = 0; i < (m_description.getTotalComponentCount() - 2) * 2; i++) {
+ hash = NumberUtils.hash(hash, m_attributes[i]);
+ }
+
+ return hash;
+ }
+
/**
* Returns true, when this segment is a closed curve (start point is equal
* to end point exactly).
@@ -723,10 +719,6 @@ boolean isClosed() {
void reverse() {
_reverseImpl();
- // because java doesn't support passing value types
- // by reference numberutils swap won't work
- // NumberUtils.swap(m_xStart, m_xEnd);
- // NumberUtils.swap(m_yStart, m_yEnd);
double origxStart = m_xStart;
double origxEnd = m_xEnd;
m_xStart = origxEnd;
@@ -737,7 +729,6 @@ void reverse() {
m_yEnd = origyStart;
for (int i = 1, n = m_description.getAttributeCount(); i < n; i++) {
- // FIXME fix stupid semantics enum
int semantics = m_description.getSemantics(i);// VertexDescription.Semantics
// semantics =
// m_description.getSemantics(i);
@@ -761,9 +752,9 @@ int _isIntersecting(Segment other, double tolerance,
return Line._isIntersectingLineLine((Line) this, (Line) other,
tolerance, bExcludeExactEndpoints);
else
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
default:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
@@ -777,9 +768,9 @@ int _intersect(Segment other, Point2D[] intersectionPoints,
return Line._intersectLineLine((Line) this, (Line) other,
intersectionPoints, paramThis, paramOther, tolerance);
else
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
default:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
@@ -790,15 +781,15 @@ int _intersect(Segment other, Point2D[] intersectionPoints,
*/
abstract double _calculateArea2DHelper(double xorg, double yorg);
- int _getEndPointOffset(int endPoint) {
- return endPoint * (m_description._getTotalComponents() - 2);
+ static int _getEndPointOffset(VertexDescription vd, int endPoint) {
+ return endPoint * (vd.getTotalComponentCount() - 2);
}
/**
* Returns the coordinate of the point on this segment for the given
* parameter value.
*/
- Point2D getCoord2D(double t) {
+ public Point2D getCoord2D(double t) {
Point2D pt = new Point2D();
getCoord2D(t, pt);
return pt;
@@ -814,7 +805,7 @@ Point2D getCoord2D(double t) {
* @param dst
* the coordinate where result will be placed.
*/
- abstract void getCoord2D(double t, Point2D dst);
+ public abstract void getCoord2D(double t, Point2D dst);
/**
* Finds a closest coordinate on this segment.
@@ -830,7 +821,7 @@ Point2D getCoord2D(double t) {
* obtain the 2D coordinate on the segment from t. To find the
* distance, call (inputPoint.sub(seg.getCoord2D(t))).length();
*/
- abstract double getClosestCoordinate(Point2D inputPoint,
+ public abstract double getClosestCoordinate(Point2D inputPoint,
boolean bExtrapolate);
/**
@@ -869,7 +860,6 @@ abstract double getClosestCoordinate(Point2D inputPoint,
public abstract int intersectionWithAxis2D(boolean bAxisX, double ordinate,
double[] resultOrdinates, double[] parameters);
- // FIXME Ask sergey what this method is for
void _reverseImpl() {
}
@@ -891,7 +881,9 @@ void _reverseImpl() {
abstract boolean _isDegenerate(double tolerance);
- abstract double _calculateSubLength(double t);
+ double _calculateSubLength(double t) { return tToLength(t); }
+
+ double _calculateSubLength(double t1, double t2) { return tToLength(t2) - tToLength(t1); }
abstract void _copyToImpl(Segment dst);
@@ -899,7 +891,7 @@ void _reverseImpl() {
* Returns subsegment between parameters t1 and t2. The attributes are
* interpolated along the length of the curve.
*/
- abstract Segment cut(double t1, double t2);
+ public abstract Segment cut(double t1, double t2);
/**
* Calculates the subsegment between parameters t1 and t2, and stores the
@@ -931,9 +923,16 @@ abstract boolean _isIntersectingPoint(Point2D pt, double tolerance,
* @return X coordinate of the intersection, or NaN, if no intersection.
*/
abstract double intersectionOfYMonotonicWithAxisX(double y, double xParallel);
+
+ /**
+ * Converts curves parameter t to the curve length. Can be expensive for curves.
+ */
+ abstract double tToLength(double t);
+
+ abstract double lengthToT(double len);
- double distance(/* const */Segment otherSegment,
- boolean bSegmentsKnownDisjoint) /* const */
+ public double distance(/* const */Segment otherSegment,
+ boolean bSegmentsKnownDisjoint)
{
// if the segments are not known to be disjoint, and
// the segments are found to touch in any way, then return 0.0
@@ -977,5 +976,11 @@ && _isIntersecting(otherSegment, 0, false) != 0) {
minDistance = distance;
return minDistance;
- }
+ }
+
+ public Geometry getBoundary() {
+ return Boundary.calculate(this, null);
+ }
+
+
}
diff --git a/src/com/esri/core/geometry/SegmentBuffer.java b/src/main/java/com/esri/core/geometry/SegmentBuffer.java
similarity index 86%
rename from src/com/esri/core/geometry/SegmentBuffer.java
rename to src/main/java/com/esri/core/geometry/SegmentBuffer.java
index 10934a64..a5d85076 100644
--- a/src/com/esri/core/geometry/SegmentBuffer.java
+++ b/src/main/java/com/esri/core/geometry/SegmentBuffer.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -55,9 +55,17 @@ public void set(Segment seg) {
Line ln = (Line) seg;
m_line = ln;
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
+
+ public void create(Geometry.Type type)
+ {
+ if (type == Geometry.Type.Line)
+ createLine();
+ else
+ throw new GeometryException("not implemented");
+ }
public void createLine() {
if (null == m_line) {
diff --git a/src/com/esri/core/geometry/SegmentFlags.java b/src/main/java/com/esri/core/geometry/SegmentFlags.java
similarity index 97%
rename from src/com/esri/core/geometry/SegmentFlags.java
rename to src/main/java/com/esri/core/geometry/SegmentFlags.java
index ab3a37e9..7f0b5da1 100644
--- a/src/com/esri/core/geometry/SegmentFlags.java
+++ b/src/main/java/com/esri/core/geometry/SegmentFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/SegmentIntersector.java b/src/main/java/com/esri/core/geometry/SegmentIntersector.java
similarity index 94%
rename from src/com/esri/core/geometry/SegmentIntersector.java
rename to src/main/java/com/esri/core/geometry/SegmentIntersector.java
index 794529fd..2bf63af3 100644
--- a/src/com/esri/core/geometry/SegmentIntersector.java
+++ b/src/main/java/com/esri/core/geometry/SegmentIntersector.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -195,7 +195,7 @@ public Point getResultPoint() {
// Performs the intersection
public boolean intersect(double tolerance, boolean b_intersecting) {
if (m_input_segments.size() != 2)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
m_tolerance = tolerance;
double small_tolerance_sqr = MathUtils.sqr(tolerance * 0.01);
@@ -213,7 +213,7 @@ public boolean intersect(double tolerance, boolean b_intersecting) {
m_param_1, m_param_2, tolerance);
if (count == 0) {
assert (count > 0);
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
Point2D[] points = new Point2D[9];
for (int i = 0; i < count; i++) {
@@ -246,25 +246,21 @@ public boolean intersect(double tolerance, boolean b_intersecting) {
double ptWeight;
- Point2D pt;
+ Point2D pt = new Point2D();
if (rank1 == rank2) {// for equal ranks use weighted sum
Point2D pt_1 = new Point2D();
line_1.getCoord2D(t1, pt_1);
- pt_1.scale(weight1);
Point2D pt_2 = new Point2D();
line_2.getCoord2D(t2, pt_2);
- pt_2.scale(weight2);
- pt = new Point2D();
- pt.add(pt_1, pt_2);
ptWeight = weight1 + weight2;
- pt.scale(1 / ptWeight);
+ double t = weight2 / ptWeight;
+ MathUtils.lerp(pt_1, pt_2, t, pt);
if (Point2D.sqrDistance(pt, pt_1)
+ Point2D.sqrDistance(pt, pt_2) > small_tolerance_sqr)
bigmove = true;
} else {// for non-equal ranks, the higher rank wins
if (rank1 > rank2) {
- pt = new Point2D();
line_1.getCoord2D(t1, pt);
ptWeight = weight1;
Point2D pt_2 = new Point2D();
@@ -272,7 +268,6 @@ public boolean intersect(double tolerance, boolean b_intersecting) {
if (Point2D.sqrDistance(pt, pt_2) > small_tolerance_sqr)
bigmove = true;
} else {
- pt = new Point2D();
line_2.getCoord2D(t2, pt);
ptWeight = weight2;
Point2D pt_1 = new Point2D();
@@ -347,10 +342,10 @@ public boolean intersect(double tolerance, boolean b_intersecting) {
return bigmove;
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
return false;
@@ -360,7 +355,7 @@ public void intersect(double tolerance, Point pt_intersector_point,
int point_rank, double point_weight, boolean b_intersecting) {
pt_intersector_point.copyTo(m_point);
if (m_input_segments.size() != 1)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
m_tolerance = tolerance;
@@ -392,17 +387,14 @@ public void intersect(double tolerance, Point pt_intersector_point,
double ptWeight;
- Point2D pt;
+ Point2D pt = new Point2D();
if (rank1 == rank2) {// for equal ranks use weighted sum
Point2D pt_1 = new Point2D();
line_1.getCoord2D(t1, pt_1);
- pt_1.scale(weight1);
Point2D pt_2 = pt_intersector_point.getXY();
- pt_2.scale(weight2);
- pt = new Point2D();
- pt.add(pt_1, pt_2);
ptWeight = weight1 + weight2;
- pt.scale(1 / ptWeight);
+ double t = weight2 / ptWeight;
+ MathUtils.lerp(pt_1, pt_2, t, pt);
} else {// for non-equal ranks, the higher rank wins
if (rank1 > rank2) {
pt = new Point2D();
@@ -441,7 +433,7 @@ public void intersect(double tolerance, Point pt_intersector_point,
return;
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
diff --git a/src/com/esri/core/geometry/SegmentIterator.java b/src/main/java/com/esri/core/geometry/SegmentIterator.java
similarity index 84%
rename from src/com/esri/core/geometry/SegmentIterator.java
rename to src/main/java/com/esri/core/geometry/SegmentIterator.java
index 0d5e1889..089f93d8 100644
--- a/src/com/esri/core/geometry/SegmentIterator.java
+++ b/src/main/java/com/esri/core/geometry/SegmentIterator.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,7 +25,17 @@
package com.esri.core.geometry;
/**
- * This class provides functionality to iterate over multipath segments.
+ * This class provides functionality to iterate over MultiPath segments.
+ *
+ * Example:
+ *
+ * SegmentIterator iterator = polygon.querySegmentIterator();
+ * while (iterator.nextPath()) {
+ * while (iterator.hasNextSegment()) {
+ * Segment segment = iterator.nextSegment();
+ * }
+ * }
+ *
*/
public class SegmentIterator {
private SegmentIteratorImpl m_impl;
@@ -115,6 +125,18 @@ public void resetToLastSegment() {
m_impl.resetToLastSegment();
}
+ /**
+ *Resets the iterator to a specific vertex.
+ *The call to next_segment will return the segment that starts at the vertex.
+ *Call to previous_segment will return the segment that starts at the previous vertex.
+ *@param vertexIndex The vertex index to reset the iterator to.
+ *@param pathIndex The path index to reset the iterator to. Used as a hint. If the path_index is wrong or -1, then the path_index is automatically calculated.
+ *
+ */
+ public void resetToVertex(int vertexIndex, int pathIndex) {
+ m_impl.resetToVertex(vertexIndex, pathIndex);
+ }
+
/**
* Indicates whether a next segment exists for the path.
*
diff --git a/src/com/esri/core/geometry/SegmentIteratorImpl.java b/src/main/java/com/esri/core/geometry/SegmentIteratorImpl.java
similarity index 90%
rename from src/com/esri/core/geometry/SegmentIteratorImpl.java
rename to src/main/java/com/esri/core/geometry/SegmentIteratorImpl.java
index 644a6767..03761997 100644
--- a/src/com/esri/core/geometry/SegmentIteratorImpl.java
+++ b/src/main/java/com/esri/core/geometry/SegmentIteratorImpl.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -51,6 +51,8 @@ final class SegmentIteratorImpl {
protected int m_segmentCount;
+ protected int m_pathBegin;
+
protected MultiPathImpl m_parent; // parent of the iterator.
protected boolean m_bCirculator; // If true, the iterator circulates around
@@ -67,6 +69,7 @@ public SegmentIteratorImpl(MultiPathImpl parent) {
m_segmentCount = _getSegmentCount(m_nextPathIndex);
m_bCirculator = false;
m_currentSegment = null;
+ m_pathBegin = -1;
m_dummyPoint = new Point2D();
}
@@ -84,6 +87,7 @@ public SegmentIteratorImpl(MultiPathImpl parent, int pointIndex) {
m_segmentCount = _getSegmentCount(m_currentPathIndex);
m_bCirculator = false;
m_currentSegment = null;
+ m_pathBegin = m_parent.getPathStart(m_currentPathIndex);
m_dummyPoint = new Point2D();
}
@@ -105,6 +109,7 @@ public SegmentIteratorImpl(MultiPathImpl parent, int pathIndex,
m_segmentCount = _getSegmentCount(m_nextPathIndex);
m_bCirculator = false;
m_currentSegment = null;
+ m_pathBegin = m_parent.getPathStart(m_currentPathIndex);
m_dummyPoint = new Point2D();
}
@@ -118,6 +123,7 @@ void resetTo(SegmentIteratorImpl src) {
m_nextPathIndex = src.m_nextPathIndex;
m_segmentCount = src.m_segmentCount;
m_bCirculator = src.m_bCirculator;
+ m_pathBegin = src.m_pathBegin;
m_currentSegment = null;
}
@@ -195,13 +201,17 @@ public void resetToLastSegment() {
}
public void resetToVertex(int vertexIndex) {
+ resetToVertex(vertexIndex, -1);
+ }
+
+ public void resetToVertex(int vertexIndex, int _pathIndex) {
if (m_currentPathIndex >= 0
&& m_currentPathIndex < m_parent.getPathCount()) {// check if we
// are in
// the
// current
// path
- int start = m_parent.getPathStart(m_currentPathIndex);
+ int start = _getPathBegin();
if (vertexIndex >= start
&& vertexIndex < m_parent.getPathEnd(m_currentPathIndex)) {
m_currentSegmentIndex = -1;
@@ -210,12 +220,21 @@ public void resetToVertex(int vertexIndex) {
}
}
- int pathIndex = m_parent.getPathIndexFromPointIndex(vertexIndex);
- m_nextPathIndex = pathIndex + 1;
- m_currentPathIndex = pathIndex;
+ int path_index;
+ if (_pathIndex >= 0 && _pathIndex < m_parent.getPathCount()
+ && vertexIndex >= m_parent.getPathStart(_pathIndex)
+ && vertexIndex < m_parent.getPathEnd(_pathIndex)) {
+ path_index = _pathIndex;
+ } else {
+ path_index = m_parent.getPathIndexFromPointIndex(vertexIndex);
+ }
+
+ m_nextPathIndex = path_index + 1;
+ m_currentPathIndex = path_index;
m_currentSegmentIndex = -1;
- m_nextSegmentIndex = vertexIndex - m_parent.getPathStart(pathIndex);
- m_segmentCount = _getSegmentCount(pathIndex);
+ m_nextSegmentIndex = vertexIndex - m_parent.getPathStart(path_index);
+ m_segmentCount = _getSegmentCount(path_index);
+ m_pathBegin = m_parent.getPathStart(m_currentPathIndex);
}
/**
@@ -231,6 +250,7 @@ public boolean nextPath() {
m_currentSegmentIndex = -1;
m_nextSegmentIndex = 0;
m_segmentCount = _getSegmentCount(m_currentPathIndex);
+ m_pathBegin = m_parent.getPathStart(m_currentPathIndex);
m_nextPathIndex++;
return true;
}
@@ -249,6 +269,7 @@ public boolean previousPath() {
m_nextSegmentIndex = 0;
m_segmentCount = _getSegmentCount(m_nextPathIndex);
m_currentPathIndex = m_nextPathIndex;
+ m_pathBegin = m_parent.getPathStart(m_currentPathIndex);
resetToLastSegment();
return true;
}
@@ -264,6 +285,7 @@ public void resetToFirstPath() {
m_segmentCount = -1;
m_nextPathIndex = 0;
m_currentPathIndex = -1;
+ m_pathBegin = -1;
}
/**
@@ -276,6 +298,7 @@ public void resetToLastPath() {
m_currentSegmentIndex = -1;
m_nextSegmentIndex = -1;
m_segmentCount = -1;
+ m_pathBegin = -1;
}
/**
@@ -293,6 +316,7 @@ public void resetToPath(int pathIndex) {
m_currentSegmentIndex = -1;
m_nextSegmentIndex = -1;
m_segmentCount = -1;
+ m_pathBegin = -1;
}
public int _getSegmentCount(int pathIndex) {
@@ -404,8 +428,6 @@ public void _updateSegment() {
AttributeStreamOfInt8 segFlagStream = m_parent
.getSegmentFlagsStreamRef();
- // FIXME Review this implementation of segment flags and the switch
- // statement below.
int segFlag = SegmentFlags.enumLineSeg;
if (segFlagStream != null)
segFlag = (segFlagStream.read(startVertexIndex) & SegmentFlags.enumSegmentMask);
@@ -418,13 +440,13 @@ public void _updateSegment() {
m_currentSegment = (Line) m_line;
break;
case SegmentFlags.enumBezierSeg:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// break;
case SegmentFlags.enumArcSeg:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
// break;
default:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
m_currentSegment.assignVertexDescription(vertexDescr);
diff --git a/src/com/esri/core/geometry/ShapeExportFlags.java b/src/main/java/com/esri/core/geometry/ShapeExportFlags.java
similarity index 98%
rename from src/com/esri/core/geometry/ShapeExportFlags.java
rename to src/main/java/com/esri/core/geometry/ShapeExportFlags.java
index 03cc9b3f..ac04ba51 100644
--- a/src/com/esri/core/geometry/ShapeExportFlags.java
+++ b/src/main/java/com/esri/core/geometry/ShapeExportFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/ShapeImportFlags.java b/src/main/java/com/esri/core/geometry/ShapeImportFlags.java
similarity index 97%
rename from src/com/esri/core/geometry/ShapeImportFlags.java
rename to src/main/java/com/esri/core/geometry/ShapeImportFlags.java
index 1b2742c9..876a983d 100644
--- a/src/com/esri/core/geometry/ShapeImportFlags.java
+++ b/src/main/java/com/esri/core/geometry/ShapeImportFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/ShapeModifiers.java b/src/main/java/com/esri/core/geometry/ShapeModifiers.java
similarity index 98%
rename from src/com/esri/core/geometry/ShapeModifiers.java
rename to src/main/java/com/esri/core/geometry/ShapeModifiers.java
index 2206c8e9..9ba3b702 100644
--- a/src/com/esri/core/geometry/ShapeModifiers.java
+++ b/src/main/java/com/esri/core/geometry/ShapeModifiers.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/ShapeType.java b/src/main/java/com/esri/core/geometry/ShapeType.java
similarity index 98%
rename from src/com/esri/core/geometry/ShapeType.java
rename to src/main/java/com/esri/core/geometry/ShapeType.java
index 17efe606..5d1fafa3 100644
--- a/src/com/esri/core/geometry/ShapeType.java
+++ b/src/main/java/com/esri/core/geometry/ShapeType.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/SimpleByteBufferCursor.java b/src/main/java/com/esri/core/geometry/SimpleByteBufferCursor.java
similarity index 97%
rename from src/com/esri/core/geometry/SimpleByteBufferCursor.java
rename to src/main/java/com/esri/core/geometry/SimpleByteBufferCursor.java
index 5b884949..e7595439 100644
--- a/src/com/esri/core/geometry/SimpleByteBufferCursor.java
+++ b/src/main/java/com/esri/core/geometry/SimpleByteBufferCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/SimpleGeometryCursor.java b/src/main/java/com/esri/core/geometry/SimpleGeometryCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/SimpleGeometryCursor.java
rename to src/main/java/com/esri/core/geometry/SimpleGeometryCursor.java
index 5ec4034d..3c185400 100644
--- a/src/com/esri/core/geometry/SimpleGeometryCursor.java
+++ b/src/main/java/com/esri/core/geometry/SimpleGeometryCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/SimpleJsonCursor.java b/src/main/java/com/esri/core/geometry/SimpleJsonCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/SimpleJsonCursor.java
rename to src/main/java/com/esri/core/geometry/SimpleJsonCursor.java
index 188d7d4d..1af987a9 100644
--- a/src/com/esri/core/geometry/SimpleJsonCursor.java
+++ b/src/main/java/com/esri/core/geometry/SimpleJsonCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/SimpleJsonParserCursor.java b/src/main/java/com/esri/core/geometry/SimpleJsonReaderCursor.java
similarity index 78%
rename from src/com/esri/core/geometry/SimpleJsonParserCursor.java
rename to src/main/java/com/esri/core/geometry/SimpleJsonReaderCursor.java
index 1d30235c..9a0793fc 100644
--- a/src/com/esri/core/geometry/SimpleJsonParserCursor.java
+++ b/src/main/java/com/esri/core/geometry/SimpleJsonReaderCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,23 +23,21 @@
*/
package com.esri.core.geometry;
-import org.codehaus.jackson.JsonParser;
+class SimpleJsonReaderCursor extends JsonReaderCursor {
-class SimpleJsonParserCursor extends JsonParserCursor {
-
- JsonParser m_jsonParser;
- JsonParser[] m_jsonParserArray;
+ JsonReader m_jsonParser;
+ JsonReader[] m_jsonParserArray;
int m_index;
int m_count;
- public SimpleJsonParserCursor(JsonParser jsonString) {
+ public SimpleJsonReaderCursor(JsonReader jsonString) {
m_jsonParser = jsonString;
m_index = -1;
m_count = 1;
}
- public SimpleJsonParserCursor(JsonParser[] jsonStringArray) {
+ public SimpleJsonReaderCursor(JsonReader[] jsonStringArray) {
m_jsonParserArray = jsonStringArray;
m_index = -1;
m_count = jsonStringArray.length;
@@ -51,7 +49,7 @@ public int getID() {
}
@Override
- public JsonParser next() {
+ public JsonReader next() {
if (m_index < m_count - 1) {
m_index++;
return m_jsonParser != null ? m_jsonParser
diff --git a/src/com/esri/core/geometry/SimpleMapGeometryCursor.java b/src/main/java/com/esri/core/geometry/SimpleMapGeometryCursor.java
similarity index 98%
rename from src/com/esri/core/geometry/SimpleMapGeometryCursor.java
rename to src/main/java/com/esri/core/geometry/SimpleMapGeometryCursor.java
index 6d6879ed..fb281b76 100644
--- a/src/com/esri/core/geometry/SimpleMapGeometryCursor.java
+++ b/src/main/java/com/esri/core/geometry/SimpleMapGeometryCursor.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/esri/core/geometry/SimpleRasterizer.java b/src/main/java/com/esri/core/geometry/SimpleRasterizer.java
new file mode 100644
index 00000000..8c6d7e46
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/SimpleRasterizer.java
@@ -0,0 +1,581 @@
+/*
+ Copyright 2013-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_EDGE;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_SIMPLE_RASTERIZER;
+import static com.esri.core.geometry.SizeOf.sizeOfIntArray;
+import static com.esri.core.geometry.SizeOf.sizeOfObjectArray;
+
+/**
+ * Simple scanline rasterizer. Caller provides a callback to draw pixels to actual surface.
+ *
+ */
+public class SimpleRasterizer {
+
+ /**
+ * Even odd fill rule
+ */
+ public final static int EVEN_ODD = 0;
+
+ /**
+ * Winding fill rule
+ */
+ public final static int WINDING = 1;
+
+ public interface ScanCallback {
+ /**
+ * Rasterizer calls this method for each scan it produced
+ * @param scans array of scans. Scans are triplets of numbers. The start X coordinate for the scan (inclusive),
+ * the end X coordinate of the scan (exclusive), the Y coordinate for the scan.
+ * @param scanCount3 The number of initialized elements in the scans array. The scan count is scanCount3 / 3.
+ */
+ void drawScan(int[] scans, int scanCount3);
+ }
+
+ public SimpleRasterizer() {
+ width_ = -1;
+ height_ = -1;
+ }
+
+ /**
+ * Sets up the rasterizer.
+ */
+ public void setup(int width, int height, ScanCallback callback)
+ {
+ width_ = width; height_ = height;
+ ySortedEdges_ = null;
+ activeEdgesTable_ = null;
+ numEdges_ = 0;
+ callback_ = callback;
+ if (scanBuffer_ == null)
+ scanBuffer_ = new int[128 * 3];
+
+ startAddingEdges();
+ }
+
+ public final int getWidth() {
+ return width_;
+ }
+
+ public final int getHeight() {
+ return height_;
+ }
+
+ /**
+ * Flushes any cached scans.
+ */
+ public final void flush() {
+ if (scanPtr_ > 0) {
+ callback_.drawScan(scanBuffer_, scanPtr_);
+ scanPtr_ = 0;
+ }
+ }
+
+ /**
+ * Adds edges of a triangle.
+ */
+ public final void addTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
+ addEdge(x1, y1, x2, y2);
+ addEdge(x2, y2, x3, y3);
+ addEdge(x1, y1, x3, y3);
+ }
+
+ /**
+ * Adds edges of the ring to the rasterizer.
+ * @param xy interleaved coordinates x1, y1, x2, y2,...
+ */
+ public final void addRing(double xy[]) {
+ for (int i = 2; i < xy.length; i += 2) {
+ addEdge(xy[i-2], xy[i - 1], xy[i], xy[i + 1]);
+ }
+ }
+
+ /**
+ * Call before starting the edges.
+ *
+ * For example to render two polygons that consist of a single ring:
+ * startAddingEdges();
+ * addRing(...);
+ * renderEdges(Rasterizer.EVEN_ODD);
+ * addRing(...);
+ * renderEdges(Rasterizer.EVEN_ODD);
+ *
+ * For example to render a polygon consisting of three rings:
+ * startAddingEdges();
+ * addRing(...);
+ * addRing(...);
+ * addRing(...);
+ * renderEdges(Rasterizer.EVEN_ODD);
+ */
+ public final void startAddingEdges() {
+ if (numEdges_ > 0) {
+ for (int i = 0; i < height_; i++) {
+ for (Edge e = ySortedEdges_[i]; e != null;) {
+ Edge p = e;
+ e = e.next;
+ p.next = null;
+ }
+
+ ySortedEdges_[i] = null;
+ }
+
+ activeEdgesTable_ = null;
+ }
+
+ minY_ = height_;
+ maxY_ = -1;
+ numEdges_ = 0;
+ }
+
+ /**
+ * Renders all edges added so far, and removes them.
+ * Calls startAddingEdges after it's done.
+ * @param fillMode Fill mode for the polygon fill can be one of two values: EVEN_ODD or WINDING.
+ *
+ * Note, as any other graphics algorithm, the scan line rasterizer doesn't require polygons
+ * to be topologically simple, or have correct ring orientation.
+ */
+ public final void renderEdges(int fillMode) {
+ evenOdd_ = fillMode == EVEN_ODD;
+ for (int line = minY_; line <= maxY_; line++) {
+ advanceAET_();
+ addNewEdgesToAET_(line);
+ emitScans_();
+ }
+
+ startAddingEdges();//reset for new edges
+ }
+
+ /**
+ * Add a single edge.
+ * @param x1
+ * @param y1
+ * @param x2
+ * @param y2
+ */
+ public final void addEdge(double x1, double y1, double x2, double y2) {
+ if (y1 == y2)
+ return;
+
+ int dir = 1;
+ if (y1 > y2) {
+ double temp;
+ temp = x1; x1 = x2; x2 = temp;
+ temp = y1; y1 = y2; y2 = temp;
+ dir = -1;
+ }
+
+ if (y2 < 0 || y1 >= height_)
+ return;
+
+ if (x1 < 0 && x2 < 0)
+ {
+ x1 = -1; x2 = -1;
+ }
+ else if (x1 >= width_ && x2 >= width_)
+ {
+ x1 = width_; x2 = width_;
+ }
+
+ //clip to extent
+ double dxdy = (x2 - x1) / (y2 - y1);
+
+ if (y2 > height_) {
+ y2 = height_;
+ x2 = dxdy * (y2 - y1) + x1;
+ }
+
+ if (y1 < 0) {
+ x1 = dxdy * (0 - y1) + x1;
+ y1 = 0;
+ }
+
+ //do not clip x unless it is too small or too big
+ int bigX = Math.max(width_ + 1, 0x7fffff);
+ if (x1 < -0x7fffff) {
+ //from earlier logic, x2 >= -1, therefore dxdy is not 0
+ y1 = (0 - x1) / dxdy + y1;
+ x1 = 0;
+ }
+ else if (x1 > bigX) {
+ //from earlier logic, x2 <= width_, therefore dxdy is not 0
+ y1 = (width_ - x1) / dxdy + y1;
+ x1 = width_;
+ }
+
+ if (x2 < -0x7fffff) {
+ //from earlier logic, x1 >= -1, therefore dxdy is not 0
+ y2 = (0 - x1) / dxdy + y1;
+ x2 = 0;
+ }
+ else if (x2 > bigX) {
+ //from earlier logic, x1 <= width_, therefore dxdy is not 0
+ y2 = (width_ - x1) / dxdy + y1;
+ x2 = width_;
+ }
+
+ int ystart = (int)y1;
+ int yend = (int)y2;
+ if (ystart == yend)
+ return;
+
+ Edge e = new Edge();
+
+ e.x = (long)(x1 * 4294967296.0);
+ e.y = ystart;
+ e.ymax = yend;
+ e.dxdy = (long)(dxdy * 4294967296.0);
+ e.dir = dir;
+
+ if (ySortedEdges_ == null) {
+ ySortedEdges_ = new Edge[height_];
+ }
+
+ e.next = ySortedEdges_[e.y];
+ ySortedEdges_[e.y] = e;
+
+ if (e.y < minY_)
+ minY_ = e.y;
+
+ if (e.ymax > maxY_)
+ maxY_ = e.ymax;
+
+ numEdges_++;
+ }
+
+ public final void fillEnvelope(Envelope2D envIn) {
+ Envelope2D env = new Envelope2D(0, 0, width_, height_);
+ if (!env.intersect(envIn))
+ return;
+
+ int x0 = (int)env.xmin;
+ int x = (int)env.xmax;
+
+ int xn = NumberUtils.snap(x0, 0, width_);
+ int xm = NumberUtils.snap(x, 0, width_);
+ if (x0 < width_ && xn < xm) {
+ int y0 = (int)env.ymin;
+ int y1 = (int)env.ymax;
+ y0 = NumberUtils.snap(y0, 0, height_);
+ y1 = NumberUtils.snap(y1, 0, height_);
+ if (y0 < height_) {
+ for (int y = y0; y < y1; y++) {
+ scanBuffer_[scanPtr_++] = xn;
+ scanBuffer_[scanPtr_++] = xm;
+ scanBuffer_[scanPtr_++] = y;
+ if (scanPtr_ == scanBuffer_.length) {
+ callback_.drawScan(scanBuffer_, scanPtr_);
+ scanPtr_ = 0;
+ }
+ }
+ }
+ }
+ }
+
+ final boolean addSegmentStroke(double x1, double y1, double x2, double y2, double half_width, boolean skip_short,
+ double[] helper_xy_10_elm) {
+ double vec_x = x2 - x1;
+ double vec_y = y2 - y1;
+ double sqr_len = vec_x * vec_x + vec_y * vec_y;
+ if (skip_short && sqr_len < (0.5 * 0.5)) {
+ return false;
+ }
+
+ boolean veryShort = !skip_short && (sqr_len < (0.00001 * 0.00001));
+ if (veryShort) {
+ vec_x = half_width + 0.00001;
+ vec_y = 0.0;
+ } else {
+ double f = half_width / Math.sqrt(sqr_len);
+ vec_x *= f;
+ vec_y *= f;
+ }
+
+ double vecA_x = -vec_y;
+ double vecA_y = vec_x;
+ double vecB_x = vec_y;
+ double vecB_y = -vec_x;
+ // extend by half width
+ x1 -= vec_x;
+ y1 -= vec_y;
+ x2 += vec_x;
+ y2 += vec_y;
+ // create rotated rectangle
+ double[] fan = helper_xy_10_elm;
+ assert (fan.length == 10);
+ fan[0] = x1 + vecA_x;
+ fan[1] = y1 + vecA_y;// fan[0].add(pt_start, vecA);
+ fan[2] = x1 + vecB_x;
+ fan[3] = y1 + vecB_y;// fan[1].add(pt_start, vecB);
+ fan[4] = x2 + vecB_x;
+ fan[5] = y2 + vecB_y;// fan[2].add(pt_end, vecB)
+ fan[6] = x2 + vecA_x;
+ fan[7] = y2 + vecA_y;// fan[3].add(pt_end, vecA)
+ fan[8] = fan[0];
+ fan[9] = fan[1];
+ addRing(fan);
+ return true;
+ }
+
+ public final ScanCallback getScanCallback() { return callback_; }
+
+ public long estimateMemorySize()
+ {
+ // callback_ is only a pointer, the actual size is accounted for in the caller of setup()
+ long size = SIZE_OF_SIMPLE_RASTERIZER +
+ (activeEdgesTable_ != null ? activeEdgesTable_.estimateMemorySize() : 0) +
+ (scanBuffer_ != null ? sizeOfIntArray(scanBuffer_.length) : 0);
+
+ if (ySortedEdges_ != null) {
+ size += sizeOfObjectArray(ySortedEdges_.length);
+ for (int i = 0; i < ySortedEdges_.length; i++) {
+ if (ySortedEdges_[i] != null) {
+ size += ySortedEdges_[i].estimateMemorySize();
+ }
+ }
+ }
+
+ if (sortBuffer_ != null) {
+ size += sizeOfObjectArray(sortBuffer_.length);
+ for (int i = 0; i < sortBuffer_.length; i++) {
+ if (sortBuffer_[i] != null) {
+ size += sortBuffer_[i].estimateMemorySize();
+ }
+ }
+ }
+
+ return size;
+ }
+
+ //PRIVATE
+
+ static class Edge {
+ long x;
+ long dxdy;
+ int y;
+ int ymax;
+ int dir;
+ Edge next;
+
+ long estimateMemorySize()
+ {
+ // next is only a pointer, the actual size is accounted for in SimpleRasterizer#estimateMemorySize
+ return SIZE_OF_EDGE;
+ }
+ }
+
+ private final void advanceAET_() {
+ if (activeEdgesTable_ == null)
+ return;
+
+ boolean needSort = false;
+ Edge prev = null;
+ for (Edge e = activeEdgesTable_; e != null; ) {
+ e.y++;
+ if (e.y == e.ymax) {
+ Edge p = e; e = e.next;
+ if (prev != null)
+ prev.next = e;
+ else
+ activeEdgesTable_ = e;
+
+ p.next = null;
+ continue;
+ }
+
+ e.x += e.dxdy;
+ if (prev != null && prev.x > e.x)
+ needSort = true;
+
+ prev = e;
+ e = e.next;
+ }
+
+ if (needSort) {
+ //resort to fix the order
+ activeEdgesTable_ = sortAET_(activeEdgesTable_);
+ }
+ }
+
+ private final void addNewEdgesToAET_(int y) {
+ if (y >= height_)
+ return;
+
+ Edge edgesOnLine = ySortedEdges_[y];
+ if (edgesOnLine != null) {
+ ySortedEdges_[y] = null;
+ edgesOnLine = sortAET_(edgesOnLine);//sort new edges
+ numEdges_ -= sortedNum_;//set in the sortAET
+
+ // merge the edges with sorted AET - O(n) operation
+ Edge aet = activeEdgesTable_;
+ boolean first = true;
+ Edge newEdge = edgesOnLine;
+ Edge prev_aet = null;
+ while (aet != null && newEdge != null) {
+ if (aet.x > newEdge.x) {
+ if (first)
+ activeEdgesTable_ = newEdge;
+
+ Edge p = newEdge.next;
+ newEdge.next = aet;
+ if (prev_aet != null) {
+ prev_aet.next = newEdge;
+ }
+
+ prev_aet = newEdge;
+ newEdge = p;
+ } else { // aet.x <= newEdges.x
+ Edge p = aet.next;
+ aet.next = newEdge;
+ if (prev_aet != null)
+ prev_aet.next = aet;
+
+ prev_aet = aet;
+ aet = p;
+ }
+
+ first = false;
+ }
+
+ if (activeEdgesTable_ == null)
+ activeEdgesTable_ = edgesOnLine;
+ }
+ }
+
+ private static int snap_(int x, int mi, int ma) {
+ return x < mi ? mi : x > ma ? ma : x;
+ }
+
+ private final void emitScans_() {
+ if (activeEdgesTable_ == null)
+ return;
+
+ int w = 0;
+ Edge e0 = activeEdgesTable_;
+ int x0 = (int)(e0.x >> 32);
+ for (Edge e = e0.next; e != null; e = e.next) {
+ if (evenOdd_)
+ w ^= 1;
+ else
+ w += e.dir;
+
+ if (e.x > e0.x) {
+ int x = (int)(e.x >> 32);
+ if (w != 0) {
+ int xx0 = snap_(x0, 0, width_);
+ int xx = snap_(x, 0, width_);
+ if (xx > xx0 && xx0 < width_) {
+ scanBuffer_[scanPtr_++] = xx0;
+ scanBuffer_[scanPtr_++] = xx;
+ scanBuffer_[scanPtr_++] = e.y;
+ if (scanPtr_ == scanBuffer_.length) {
+ callback_.drawScan(scanBuffer_, scanPtr_);
+ scanPtr_ = 0;
+ }
+ }
+ }
+
+ e0 = e;
+ x0 = x;
+ }
+ }
+ }
+
+ static private class EdgeComparator implements Comparator {
+ @Override
+ public int compare(Edge o1, Edge o2) {
+ if (o1 == o2)
+ return 0;
+
+ return o1.x < o2.x ? -1 : o1.x > o2.x ? 1 : 0;
+ }
+ }
+
+ private final static EdgeComparator edgeCompare_ = new EdgeComparator();
+
+ private final Edge sortAET_(Edge aet) {
+ int num = 0;
+ for (Edge e = aet; e != null; e = e.next)
+ num++;
+
+ sortedNum_ = num;
+ if (num == 1)
+ return aet;
+
+ if (sortBuffer_ == null)
+ sortBuffer_ = new Edge[Math.max(num, 16)];
+
+ else if (sortBuffer_.length < num)
+ sortBuffer_ = new Edge[Math.max(num, sortBuffer_.length * 2)];
+
+ {
+ int i = 0;
+ for (Edge e = aet; e != null; e = e.next)
+ sortBuffer_[i++] = e;
+ }
+
+ if (num == 2) {
+ if (sortBuffer_[0].x > sortBuffer_[1].x) {
+ Edge tmp = sortBuffer_[0];
+ sortBuffer_[0] = sortBuffer_[1];
+ sortBuffer_[1] = tmp;
+ }
+ }
+ else {
+ Arrays.sort(sortBuffer_, 0, num, edgeCompare_);
+ }
+
+ aet = sortBuffer_[0]; sortBuffer_[0] = null;
+ Edge prev = aet;
+ for (int i = 1; i < num; i++) {
+ prev.next = sortBuffer_[i];
+ prev = sortBuffer_[i];
+ sortBuffer_[i] = null;
+ }
+
+ prev.next = null;
+ return aet;
+ }
+
+ private Edge activeEdgesTable_;
+ private Edge[] ySortedEdges_;
+ private Edge[] sortBuffer_;
+ private int[] scanBuffer_;
+ int scanPtr_;
+ private ScanCallback callback_;
+ private int width_;
+ private int height_;
+ private int minY_;
+ private int maxY_;
+ private int numEdges_;
+ private int sortedNum_;
+ private boolean evenOdd_;
+}
+
diff --git a/src/com/esri/core/geometry/Simplificator.java b/src/main/java/com/esri/core/geometry/Simplificator.java
similarity index 69%
rename from src/com/esri/core/geometry/Simplificator.java
rename to src/main/java/com/esri/core/geometry/Simplificator.java
index 1c6db3ce..a5102528 100644
--- a/src/com/esri/core/geometry/Simplificator.java
+++ b/src/main/java/com/esri/core/geometry/Simplificator.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -33,19 +33,21 @@ class Simplificator {
private AttributeStreamOfInt32 m_bunchEdgeIndices;
// private AttributeStreamOfInt32 m_orphanVertices;
- private int m_dbgCounter;
private int m_sortedVerticesListIndex;
private int m_userIndexSortedIndexToVertex;
private int m_userIndexSortedAngleIndexToVertex;
private int m_nextVertexToProcess;
private int m_firstCoincidentVertex;
- private int m_knownSimpleResult;
- private boolean m_bWinding;
+ //private int m_knownSimpleResult;
+ private boolean m_fixSelfTangency;
+ private ProgressTracker m_progressTracker;
+ private int[] m_ar = null;
+ private int[] m_br = null;
private void _beforeRemoveVertex(int vertex, boolean bChangePathFirst) {
int vertexlistIndex = m_shape.getUserIndex(vertex,
m_userIndexSortedIndexToVertex);
- // _ASSERT(m_sortedVertices.getData(vertexlistIndex) != 0xdeadbeef);
+
if (m_nextVertexToProcess == vertexlistIndex) {
m_nextVertexToProcess = m_sortedVertices
.getNext(m_nextVertexToProcess);
@@ -64,20 +66,40 @@ private void _beforeRemoveVertex(int vertex, boolean bChangePathFirst) {
int first = m_shape.getFirstVertex(path);
if (first == vertex) {
int next = m_shape.getNextVertex(vertex);
- if (next != vertex)
- m_shape.setFirstVertex_(path, next);
- else {
- m_shape.setFirstVertex_(path, -1);
- m_shape.setLastVertex_(path, -1);
+ if (next != vertex) {
+ int p = m_shape.getPathFromVertex(next);
+ if (p == path) {
+ m_shape.setFirstVertex_(path, next);
+ return;
+ }
+ else {
+ int prev = m_shape.getPrevVertex(vertex);
+ if (prev != vertex) {
+ p = m_shape.getPathFromVertex(prev);
+ if (p == path) {
+ m_shape.setFirstVertex_(path, prev);
+ return;
+ }
+ }
+ }
}
+
+ m_shape.setFirstVertex_(path, -1);
+ m_shape.setLastVertex_(path, -1);
}
}
}
}
- static class SimplificatorAngleComparer extends
+ static private class SimplificatorAngleComparer extends
AttributeStreamOfInt32.IntComparator {
- Simplificator m_parent;
+ private Simplificator m_parent;
+ private Point2D pt1 = new Point2D();
+ private Point2D pt2 = new Point2D();
+ private Point2D pt10 = new Point2D();
+ private Point2D pt20 = new Point2D();
+ private Point2D v1 = new Point2D();
+ private Point2D v2 = new Point2D();
public SimplificatorAngleComparer(Simplificator parent) {
m_parent = parent;
@@ -85,19 +107,35 @@ public SimplificatorAngleComparer(Simplificator parent) {
@Override
public int compare(int v1, int v2) {
- return m_parent._compareAngles(v1, v2);
+ return _compareAngles(v1, v2);
}
+ private int _compareAngles(int index1, int index2) {
+ int vert1 = m_parent.m_bunchEdgeEndPoints.get(index1);
+ m_parent.m_shape.getXY(vert1, pt1);
+ int vert2 = m_parent.m_bunchEdgeEndPoints.get(index2);
+ m_parent.m_shape.getXY(vert2, pt2);
+
+ if (pt1.isEqual(pt2))
+ return 0;// overlap case
+
+ int vert10 = m_parent.m_bunchEdgeCenterPoints.get(index1);
+ m_parent.m_shape.getXY(vert10, pt10);
+
+ int vert20 = m_parent.m_bunchEdgeCenterPoints.get(index2);
+ m_parent.m_shape.getXY(vert20, pt20);
+
+ v1.sub(pt1, pt10);
+ v2.sub(pt2, pt20);
+ int result = Point2D._compareVectors(v1, v2);
+ return result;
+ }
}
private boolean _processBunch() {
boolean bModified = false;
- int iter = 0;
Point2D ptCenter = new Point2D();
while (true) {
- m_dbgCounter++;// only for debugging
- iter++;
- // _ASSERT(iter < 10);
if (m_bunchEdgeEndPoints == null) {
m_bunchEdgeEndPoints = new AttributeStreamOfInt32(0);
m_bunchEdgeCenterPoints = new AttributeStreamOfInt32(0);
@@ -113,25 +151,17 @@ private boolean _processBunch() {
boolean bFirst = true;
while (currentVertex != m_nextVertexToProcess) {
int v = m_sortedVertices.getData(currentVertex);
- {// debug
- Point2D pt = new Point2D();
- m_shape.getXY(v, pt);
- double y = pt.x;
- }
if (bFirst) {
m_shape.getXY(v, ptCenter);
bFirst = false;
}
int vertP = m_shape.getPrevVertex(v);
int vertN = m_shape.getNextVertex(v);
- // _ASSERT(vertP != vertN || m_shape.getPrevVertex(vertN) == v
- // && m_shape.getNextVertex(vertP) == v);
int id = m_shape.getUserIndex(vertP,
m_userIndexSortedAngleIndexToVertex);
if (id != 0xdeadbeef)// avoid adding a point twice
{
- // _ASSERT(id == -1);
m_bunchEdgeEndPoints.add(vertP);
m_shape.setUserIndex(vertP,
m_userIndexSortedAngleIndexToVertex, 0xdeadbeef);// mark
@@ -149,7 +179,6 @@ private boolean _processBunch() {
m_userIndexSortedAngleIndexToVertex);
if (id2 != 0xdeadbeef) // avoid adding a point twice
{
- // _ASSERT(id2 == -1);
m_bunchEdgeEndPoints.add(vertN);
m_shape.setUserIndex(vertN,
m_userIndexSortedAngleIndexToVertex, 0xdeadbeef);// mark
@@ -173,8 +202,6 @@ private boolean _processBunch() {
// the edge, connecting the endpoint with the bunch center)
m_bunchEdgeIndices.Sort(0, m_bunchEdgeIndices.size(),
new SimplificatorAngleComparer(this));
- // SORTDYNAMICARRAYEX(m_bunchEdgeIndices, int, 0,
- // m_bunchEdgeIndices.size(), SimplificatorAngleComparer, this);
for (int i = 0, n = m_bunchEdgeIndices.size(); i < n; i++) {
int indexL = m_bunchEdgeIndices.get(i);
@@ -183,11 +210,6 @@ private boolean _processBunch() {
m_userIndexSortedAngleIndexToVertex, i);// rember the
// sort by angle
// order
- {// debug
- Point2D pt = new Point2D();
- m_shape.getXY(vertex, pt);
- double y = pt.x;
- }
}
boolean bCrossOverResolved = _processCrossOvers(ptCenter);// see of
@@ -238,7 +260,6 @@ private boolean _processCrossOvers(Point2D ptCenter) {
int vertexB1 = m_bunchEdgeEndPoints.get(edgeindex1);
int vertexB2 = m_bunchEdgeEndPoints.get(edgeindex2);
- // _ASSERT(vertexB2 != vertexB1);
int vertexA1 = m_shape.getNextVertex(vertexB1);
if (!m_shape.isEqualXY(vertexA1, ptCenter))
@@ -247,9 +268,6 @@ private boolean _processCrossOvers(Point2D ptCenter) {
if (!m_shape.isEqualXY(vertexA2, ptCenter))
vertexA2 = m_shape.getPrevVertex(vertexB2);
- // _ASSERT(m_shape.isEqualXY(vertexA1, vertexA2));
- // _ASSERT(m_shape.isEqualXY(vertexA1, ptCenter));
-
boolean bDirection1 = _getDirection(vertexA1, vertexB1);
boolean bDirection2 = _getDirection(vertexA2, vertexB2);
int vertexC1 = bDirection1 ? m_shape.getPrevVertex(vertexA1)
@@ -315,9 +333,6 @@ else if (_removeSpike(vertexC2))
if (!m_shape.isEqualXY(vertexA2, ptCenter))
vertexA2 = m_shape.getPrevVertex(vertexB2);
- // _ASSERT(m_shape.isEqualXY(vertexA1, vertexA2));
- // _ASSERT(m_shape.isEqualXY(vertexA1, ptCenter));
-
boolean bDirection1 = _getDirection(vertexA1, vertexB1);
boolean bDirection2 = _getDirection(vertexA2, vertexB2);
int vertexC1 = bDirection1 ? m_shape.getPrevVertex(vertexA1)
@@ -339,9 +354,11 @@ else if (_removeSpike(vertexC2))
return bFound;
}
- static class SimplificatorVertexComparer extends
+ static private class SimplificatorVertexComparer extends
AttributeStreamOfInt32.IntComparator {
- Simplificator m_parent;
+ private Simplificator m_parent;
+ private Point2D pt1 = new Point2D();
+ private Point2D pt2 = new Point2D();
SimplificatorVertexComparer(Simplificator parent) {
m_parent = parent;
@@ -349,15 +366,34 @@ static class SimplificatorVertexComparer extends
@Override
public int compare(int v1, int v2) {
- return m_parent._compareVerticesSimple(v1, v2);
+ return _compareVerticesSimple(v1, v2);
}
+ private int _compareVerticesSimple(int v1, int v2) {
+ m_parent.m_shape.getXY(v1, pt1);
+ m_parent.m_shape.getXY(v2, pt2);
+ int res = pt1.compare(pt2);
+ if (res == 0) {// sort equal vertices by the path ID
+ int i1 = m_parent.m_shape.getPathFromVertex(v1);
+ int i2 = m_parent.m_shape.getPathFromVertex(v2);
+ res = i1 < i2 ? -1 : (i1 == i2 ? 0 : 1);
+ }
+
+ return res;
+ }
}
private boolean _simplify() {
+ if (m_shape.getGeometryType(m_geometry) == Polygon.Type.Polygon.value()
+ && m_shape.getFillRule(m_geometry) == Polygon.FillRule.enumFillRuleWinding)
+
+ {
+ TopologicalOperations ops = new TopologicalOperations();
+ ops.planarSimplifyNoCrackingAndCluster(m_fixSelfTangency,
+ m_shape, m_geometry, m_progressTracker);
+ assert (m_shape.getFillRule(m_geometry) == Polygon.FillRule.enumFillRuleOddEven);
+ }
boolean bChanged = false;
- boolean bNeedWindingRepeat = true;
- boolean bWinding = false;
m_userIndexSortedIndexToVertex = -1;
m_userIndexSortedAngleIndexToVertex = -1;
@@ -381,8 +417,6 @@ private boolean _simplify() {
// Sort
verticesSorter.Sort(0, pointCount,
new SimplificatorVertexComparer(this));
- // SORTDYNAMICARRAYEX(verticesSorter, int, 0, pointCount,
- // SimplificatorVertexComparer, this);
// Copy sorted vertices to the m_sortedVertices list. Make a mapping
// from the edit shape vertices to the sorted vertices.
@@ -399,11 +433,6 @@ private boolean _simplify() {
m_sortedVerticesListIndex = m_sortedVertices.createList(0);
for (int i = 0; i < pointCount; i++) {
int vertex = verticesSorter.get(i);
- {// debug
- Point2D pt = new Point2D();
- m_shape.getXY(vertex, pt);// for debugging
- double y = pt.x;
- }
int vertexlistIndex = m_sortedVertices.addElement(
m_sortedVerticesListIndex, vertex);
m_shape.setUserIndex(vertex, m_userIndexSortedIndexToVertex,
@@ -427,119 +456,100 @@ private boolean _simplify() {
if (_cleanupSpikes())// cleanup any spikes on the polygon.
bChanged = true;
- // External iteration loop for the simplificator.
- // ST. I am not sure if it actually needs this loop. TODO: figure this
- // out.
- while (bNeedWindingRepeat) {
- bNeedWindingRepeat = false;
-
- int max_iter = m_shape.getPointCount(m_geometry) + 10 > 30 ? 1000
- : (m_shape.getPointCount(m_geometry) + 10)
- * (m_shape.getPointCount(m_geometry) + 10);
-
- // Simplify polygon
- int iRepeatNum = 0;
- boolean bNeedRepeat = false;
+ // Simplify polygon
+ int iRepeatNum = 0;
+ boolean bNeedRepeat = false;
- // Internal iteration loop for the simplificator.
- // ST. I am not sure if it actually needs this loop. TODO: figure
- // this out.
- do// while (bNeedRepeat);
- {
- bNeedRepeat = false;
-
- boolean bVertexRecheck = false;
- m_firstCoincidentVertex = -1;
- int coincidentCount = 0;
- Point2D ptFirst = new Point2D();
- Point2D pt = new Point2D();
- // Main loop of the simplificator. Go through the vertices and
- // for those that have same coordinates,
- for (int vlistindex = m_sortedVertices
- .getFirst(m_sortedVerticesListIndex); vlistindex != IndexMultiDCList
- .nullNode();) {
- int vertex = m_sortedVertices.getData(vlistindex);
- {// debug
- // Point2D pt = new Point2D();
- m_shape.getXY(vertex, pt);
- double d = pt.x;
- }
-
- if (m_firstCoincidentVertex != -1) {
- // Point2D pt = new Point2D();
- m_shape.getXY(vertex, pt);
- if (ptFirst.isEqual(pt)) {
- coincidentCount++;
- } else {
- ptFirst.setCoords(pt);
- m_nextVertexToProcess = vlistindex;// we remeber the
- // next index in
- // the member
- // variable to
- // allow it to
- // be updated if
- // a vertex is
- // removed
- // inside of the
- // _ProcessBunch.
- if (coincidentCount > 0) {
- boolean result = _processBunch();// process a
- // bunch of
- // coinciding
- // vertices
- if (result) {// something has changed.
- // Note that ProcessBunch may
- // change m_nextVertexToProcess
- // and m_firstCoincidentVertex.
- bNeedRepeat = true;
- if (m_nextVertexToProcess != IndexMultiDCList
- .nullNode()) {
- int v = m_sortedVertices
- .getData(m_nextVertexToProcess);
- m_shape.getXY(v, ptFirst);
- }
+ // Internal iteration loop for the simplificator.
+ // ST. I am not sure if it actually needs this loop. TODO: figure
+ // this out.
+ do// while (bNeedRepeat);
+ {
+ bNeedRepeat = false;
+
+ m_firstCoincidentVertex = -1;
+ int coincidentCount = 0;
+ Point2D ptFirst = new Point2D();
+ Point2D pt = new Point2D();
+ // Main loop of the simplificator. Go through the vertices and
+ // for those that have same coordinates,
+ for (int vlistindex = m_sortedVertices
+ .getFirst(m_sortedVerticesListIndex); vlistindex != IndexMultiDCList
+ .nullNode();) {
+ int vertex = m_sortedVertices.getData(vlistindex);
+
+ if (m_firstCoincidentVertex != -1) {
+ // Point2D pt = new Point2D();
+ m_shape.getXY(vertex, pt);
+ if (ptFirst.isEqual(pt)) {
+ coincidentCount++;
+ } else {
+ ptFirst.setCoords(pt);
+ m_nextVertexToProcess = vlistindex;// we remeber the
+ // next index in
+ // the member
+ // variable to
+ // allow it to
+ // be updated if
+ // a vertex is
+ // removed
+ // inside of the
+ // _ProcessBunch.
+ if (coincidentCount > 0) {
+ boolean result = _processBunch();// process a
+ // bunch of
+ // coinciding
+ // vertices
+ if (result) {// something has changed.
+ // Note that ProcessBunch may
+ // change m_nextVertexToProcess
+ // and m_firstCoincidentVertex.
+ bNeedRepeat = true;
+ if (m_nextVertexToProcess != IndexMultiDCList
+ .nullNode()) {
+ int v = m_sortedVertices
+ .getData(m_nextVertexToProcess);
+ m_shape.getXY(v, ptFirst);
}
}
-
- vlistindex = m_nextVertexToProcess;
- m_firstCoincidentVertex = vlistindex;
- coincidentCount = 0;
}
- } else {
+
+ vlistindex = m_nextVertexToProcess;
m_firstCoincidentVertex = vlistindex;
- m_shape.getXY(m_sortedVertices.getData(vlistindex),
- ptFirst);
coincidentCount = 0;
}
-
- vlistindex = m_sortedVertices.getNext(vlistindex);
- }
-
- m_nextVertexToProcess = -1;
-
- if (coincidentCount > 0) {
- boolean result = _processBunch();
- if (result)
- bNeedRepeat = true;
+ } else {
+ m_firstCoincidentVertex = vlistindex;
+ m_shape.getXY(m_sortedVertices.getData(vlistindex),
+ ptFirst);
+ coincidentCount = 0;
}
- if (iRepeatNum++ > 10) {
- throw new GeometryException("internal error.");
- }
+ if (vlistindex != -1)//vlistindex can be set to -1 after ProcessBunch call above
+ vlistindex = m_sortedVertices.getNext(vlistindex);
+ }
- if (bNeedRepeat)
- _fixOrphanVertices();// fix broken structure of the shape
+ m_nextVertexToProcess = -1;
- if (_cleanupSpikes())
+ if (coincidentCount > 0) {
+ boolean result = _processBunch();
+ if (result)
bNeedRepeat = true;
+ }
- bNeedWindingRepeat |= bNeedRepeat && bWinding;
+ if (iRepeatNum++ > 10) {
+ throw GeometryException.GeometryInternalError();
+ }
+
+ if (bNeedRepeat)
+ _fixOrphanVertices();// fix broken structure of the shape
- bChanged |= bNeedRepeat;
+ if (_cleanupSpikes())
+ bNeedRepeat = true;
- } while (bNeedRepeat);
+ bChanged |= bNeedRepeat;
- }// while (bNeedWindingRepeat)
+ } while (bNeedRepeat);
// Now process rings. Fix ring orientation and determine rings that need
// to be deleted.
@@ -548,18 +558,15 @@ private boolean _simplify() {
m_shape.removeUserIndex(m_userIndexSortedAngleIndexToVertex);
bChanged |= RingOrientationFixer.execute(m_shape, m_geometry,
- m_sortedVertices);
+ m_sortedVertices, m_fixSelfTangency);
return bChanged;
}
private boolean _getDirection(int vert1, int vert2) {
if (m_shape.getNextVertex(vert2) == vert1) {
- // _ASSERT(m_shape.getPrevVertex(vert1) == vert2);
return false;
} else {
- // _ASSERT(m_shape.getPrevVertex(vert2) == vert1);
- // _ASSERT(m_shape.getNextVertex(vert1) == vert2);
return true;
}
}
@@ -567,8 +574,6 @@ private boolean _getDirection(int vert1, int vert2) {
private boolean _detectAndResolveCrossOver(boolean bDirection1,
boolean bDirection2, int vertexB1, int vertexA1, int vertexC1,
int vertexB2, int vertexA2, int vertexC2) {
- // _ASSERT(!m_shape.isEqualXY(vertexB1, vertexB2));
- // _ASSERT(!m_shape.isEqualXY(vertexC1, vertexC2));
if (vertexA1 == vertexA2) {
_removeAngleSortInfo(vertexB1);
@@ -576,17 +581,6 @@ private boolean _detectAndResolveCrossOver(boolean bDirection1,
return false;
}
- // _ASSERT(!m_shape.isEqualXY(vertexB1, vertexC2));
- // _ASSERT(!m_shape.isEqualXY(vertexB1, vertexC1));
- // _ASSERT(!m_shape.isEqualXY(vertexB2, vertexC2));
- // _ASSERT(!m_shape.isEqualXY(vertexB2, vertexC1));
- // _ASSERT(!m_shape.isEqualXY(vertexA1, vertexB1));
- // _ASSERT(!m_shape.isEqualXY(vertexA1, vertexC1));
- // _ASSERT(!m_shape.isEqualXY(vertexA2, vertexB2));
- // _ASSERT(!m_shape.isEqualXY(vertexA2, vertexC2));
-
- // _ASSERT(m_shape.isEqualXY(vertexA1, vertexA2));
-
// get indices of the vertices for the angle sort.
int iB1 = m_shape.getUserIndex(vertexB1,
m_userIndexSortedAngleIndexToVertex);
@@ -596,44 +590,42 @@ private boolean _detectAndResolveCrossOver(boolean bDirection1,
m_userIndexSortedAngleIndexToVertex);
int iC2 = m_shape.getUserIndex(vertexC2,
m_userIndexSortedAngleIndexToVertex);
- // _ASSERT(iB1 >= 0);
- // _ASSERT(iC1 >= 0);
- // _ASSERT(iB2 >= 0);
- // _ASSERT(iC2 >= 0);
// Sort the indices to restore the angle-sort order
- int[] ar = new int[8];
- int[] br = new int[4];
-
- ar[0] = 0;
- br[0] = iB1;
- ar[1] = 0;
- br[1] = iC1;
- ar[2] = 1;
- br[2] = iB2;
- ar[3] = 1;
- br[3] = iC2;
+
+ if (m_ar == null) {
+ m_ar = new int[8];
+ m_br = new int[4];
+ }
+ m_ar[0] = 0;
+ m_br[0] = iB1;
+ m_ar[1] = 0;
+ m_br[1] = iC1;
+ m_ar[2] = 1;
+ m_br[2] = iB2;
+ m_ar[3] = 1;
+ m_br[3] = iC2;
for (int j = 1; j < 4; j++)// insertion sort
{
- int key = br[j];
- int data = ar[j];
+ int key = m_br[j];
+ int data = m_ar[j];
int i = j - 1;
- while (i >= 0 && br[i] > key) {
- br[i + 1] = br[i];
- ar[i + 1] = ar[i];
+ while (i >= 0 && m_br[i] > key) {
+ m_br[i + 1] = m_br[i];
+ m_ar[i + 1] = m_ar[i];
i--;
}
- br[i + 1] = key;
- ar[i + 1] = data;
+ m_br[i + 1] = key;
+ m_ar[i + 1] = data;
}
int detector = 0;
- if (ar[0] != 0)
+ if (m_ar[0] != 0)
detector |= 1;
- if (ar[1] != 0)
+ if (m_ar[1] != 0)
detector |= 2;
- if (ar[2] != 0)
+ if (m_ar[2] != 0)
detector |= 4;
- if (ar[3] != 0)
+ if (m_ar[3] != 0)
detector |= 8;
if (detector != 5 && detector != 10)// not an overlap
return false;
@@ -675,19 +667,8 @@ private boolean _detectAndResolveCrossOver(boolean bDirection1,
private void _resolveOverlap(boolean bDirection1, boolean bDirection2,
int vertexA1, int vertexB1, int vertexA2, int vertexB2) {
- if (m_bWinding) {
- _resolveOverlapWinding(bDirection1, bDirection2, vertexA1,
- vertexB1, vertexA2, vertexB2);
- } else {
- _resolveOverlapOddEven(bDirection1, bDirection2, vertexA1,
- vertexB1, vertexA2, vertexB2);
- }
- }
-
- private void _resolveOverlapWinding(boolean bDirection1,
- boolean bDirection2, int vertexA1, int vertexB1, int vertexA2,
- int vertexB2) {
- throw new GeometryException("not implemented.");
+ _resolveOverlapOddEven(bDirection1, bDirection2, vertexA1,
+ vertexB1, vertexA2, vertexB2);
}
private void _resolveOverlapOddEven(boolean bDirection1,
@@ -695,8 +676,6 @@ private void _resolveOverlapOddEven(boolean bDirection1,
int vertexB2) {
if (bDirection1 != bDirection2) {
if (bDirection1) {
- // _ASSERT(m_shape.getNextVertex(vertexA1) == vertexB1);
- // _ASSERT(m_shape.getNextVertex(vertexB2) == vertexA2);
m_shape.setNextVertex_(vertexA1, vertexA2); // B1< B2
m_shape.setPrevVertex_(vertexA2, vertexA1); // | |
m_shape.setNextVertex_(vertexB2, vertexB1); // | |
@@ -707,19 +686,17 @@ private void _resolveOverlapOddEven(boolean bDirection1,
m_shape.removeVertexInternal_(vertexA2, true);
_removeAngleSortInfo(vertexA1);
_transferVertexData(vertexB2, vertexB1);
- _beforeRemoveVertex(vertexB2, false);
+ _beforeRemoveVertex(vertexB2, true);
m_shape.removeVertexInternal_(vertexB2, false);
_removeAngleSortInfo(vertexB1);
} else {
- // _ASSERT(m_shape.getNextVertex(vertexB1) == vertexA1);
- // _ASSERT(m_shape.getNextVertex(vertexA2) == vertexB2);
m_shape.setNextVertex_(vertexA2, vertexA1); // B1 B2<
m_shape.setPrevVertex_(vertexA1, vertexA2); // | |
m_shape.setNextVertex_(vertexB1, vertexB2); // | |
m_shape.setPrevVertex_(vertexB2, vertexB1); // A1< A2
_transferVertexData(vertexA2, vertexA1);
- _beforeRemoveVertex(vertexA2, false);
+ _beforeRemoveVertex(vertexA2, true);
m_shape.removeVertexInternal_(vertexA2, false);
_removeAngleSortInfo(vertexA1);
_transferVertexData(vertexB2, vertexB1);
@@ -729,15 +706,6 @@ private void _resolveOverlapOddEven(boolean bDirection1,
}
} else// bDirection1 == bDirection2
{
- if (!bDirection1) {
- // _ASSERT(m_shape.getNextVertex(vertexB1) == vertexA1);
- // _ASSERT(m_shape.getNextVertex(vertexB2) == vertexA2);
- } else {
- // _ASSERT(m_shape.getNextVertex(vertexA1) == vertexB1);
- // _ASSERT(m_shape.getNextVertex(vertexA2) == vertexB2);
- }
-
- // if (m_shape._RingParentageCheckInternal(vertexA1, vertexA2))
{
int a1 = bDirection1 ? vertexA1 : vertexB1;
int a2 = bDirection2 ? vertexA2 : vertexB2;
@@ -748,17 +716,17 @@ private void _resolveOverlapOddEven(boolean bDirection1,
// m_shape.dbgVerifyIntegrity(a2);//debug
boolean bVisitedA1 = false;
- m_shape.setNextVertex_(a1, a2); // ^ | <--- ^ \ --.
- m_shape.setNextVertex_(a2, a1); // | | | ^ | |
- m_shape.setPrevVertex_(b1, b2); // | | | | | |
- m_shape.setPrevVertex_(b2, b1); // | | | | | |
- int v = b2; // | | | | =>| |
- while (v != a2) // | | . | | -. |
- { // | <-- | | | ./ | |
- int prev = m_shape.getPrevVertex(v); // | | | | | | | |
- int next = m_shape.getNextVertex(v); // <-+---<--- |
- // <-+---<--- |
- m_shape.setPrevVertex_(v, next); // --------. <--------
+ m_shape.setNextVertex_(a1, a2);
+ m_shape.setNextVertex_(a2, a1);
+ m_shape.setPrevVertex_(b1, b2);
+ m_shape.setPrevVertex_(b2, b1);
+ int v = b2;
+ while (v != a2)
+ {
+ int prev = m_shape.getPrevVertex(v);
+ int next = m_shape.getNextVertex(v);
+
+ m_shape.setPrevVertex_(v, next);
m_shape.setNextVertex_(v, prev);
bVisitedA1 |= v == a1;
v = next;
@@ -789,12 +757,6 @@ private void _resolveOverlapOddEven(boolean bDirection1,
// m_shape.dbgVerifyIntegrity(b1);//debug
// m_shape.dbgVerifyIntegrity(a1);//debug
}
- // else
- // {
- // m_shape._ReverseRingInternal(vertexA2);
- // _ResolveOverlapOddEven(bDirection1, !bDirection2, vertexA1,
- // vertexB1, vertexA2, vertexB2);
- // }
}
}
@@ -843,7 +805,6 @@ private boolean _removeSpike(int vertexIn) {
// m_shape.dbgVerifyIntegrity(vertex);//debug
int vertex = vertexIn;
- // _ASSERT(m_shape.isEqualXY(m_shape.getNextVertex(vertex),
// m_shape.getPrevVertex(vertex)));
boolean bFound = false;
while (true) {
@@ -900,12 +861,10 @@ private void _fixOrphanVertices() {
int pathSize = 1;
for (int vertex = m_shape.getNextVertex(first); vertex != first; vertex = m_shape
.getNextVertex(vertex)) {
- // _ASSERT(m_shape.getPathFromVertex(vertex) == -1);
m_shape.setPathToVertex_(vertex, path);
- // _ASSERT(m_shape.getNextVertex(m_shape.getPrevVertex(vertex))
- // == vertex);
pathSize++;
}
+ m_shape.setRingAreaValid_(path,false);
m_shape.setPathSize_(path, pathSize);
m_shape.setLastVertex_(path, m_shape.getPrevVertex(first));
geometrySize += pathSize;
@@ -913,40 +872,29 @@ private void _fixOrphanVertices() {
path = m_shape.getNextPath(path);
}
- // produce new paths for the orphan vertices.
+ // Some vertices do not belong to any path. We have to create new path
+ // objects for those.
+ // Produce new paths for the orphan vertices.
for (int node = m_sortedVertices.getFirst(m_sortedVertices
.getFirstList()); node != -1; node = m_sortedVertices
.getNext(node)) {
int vertex = m_sortedVertices.getData(node);
if (m_shape.getPathFromVertex(vertex) != -1)
continue;
- int path = m_shape.insertPath(m_geometry, -1);
- int pathSize = 0;
- int first = vertex;
- while (true) {
- m_shape.setPathToVertex_(vertex, path);
- pathSize++;
- int next = m_shape.getNextVertex(vertex);
- // _ASSERT(m_shape.getNextVertex(m_shape.getPrevVertex(vertex))
- // == vertex);
- if (next == first)
- break;
- vertex = next;
- }
-
- m_shape.setClosedPath(path, true);
-
- m_shape.setPathSize_(path, pathSize);
- m_shape.setFirstVertex_(path, first);
- m_shape.setLastVertex_(path, m_shape.getPrevVertex(first));
- geometrySize += pathSize;
+
+ int path = m_shape.insertClosedPath_(m_geometry, -1, vertex, vertex, null);
+ geometrySize += m_shape.getPathSize(path);
pathCount++;
}
+
m_shape.setGeometryPathCount_(m_geometry, pathCount);
- int totalPointCount = m_shape.getTotalPointCount()
- - m_shape.getPointCount(m_geometry);
m_shape.setGeometryVertexCount_(m_geometry, geometrySize);
- m_shape.setTotalPointCount_(totalPointCount + geometrySize);
+ int totalPointCount = 0;
+ for (int geometry = m_shape.getFirstGeometry(); geometry != -1; geometry = m_shape.getNextGeometry(geometry)) {
+ totalPointCount += m_shape.getPointCount(geometry);
+ }
+
+ m_shape.setTotalPointCount_(totalPointCount);
}
private int _getNextEdgeIndex(int indexIn) {
@@ -979,53 +927,16 @@ private void _removeAngleSortInfo(int vertex) {
}
protected Simplificator() {
- m_dbgCounter = 0;
}
public static boolean execute(EditShape shape, int geometry,
- int knownSimpleResult) {
+ int knownSimpleResult, boolean fixSelfTangency, ProgressTracker progressTracker) {
Simplificator simplificator = new Simplificator();
simplificator.m_shape = shape;
- // simplificator.m_bWinding = bWinding;
simplificator.m_geometry = geometry;
- simplificator.m_knownSimpleResult = knownSimpleResult;
+ //simplificator.m_knownSimpleResult = knownSimpleResult;
+ simplificator.m_fixSelfTangency = fixSelfTangency;
+ simplificator.m_progressTracker = progressTracker;
return simplificator._simplify();
}
-
- int _compareVerticesSimple(int v1, int v2) {
- Point2D pt1 = new Point2D();
- m_shape.getXY(v1, pt1);
- Point2D pt2 = new Point2D();
- m_shape.getXY(v2, pt2);
- int res = pt1.compare(pt2);
- return res;
- }
-
- int _compareAngles(int index1, int index2) {
- int vert1 = m_bunchEdgeEndPoints.get(index1);
- Point2D pt1 = new Point2D();
- m_shape.getXY(vert1, pt1);
- Point2D pt2 = new Point2D();
- int vert2 = m_bunchEdgeEndPoints.get(index2);
- m_shape.getXY(vert2, pt2);
-
- if (pt1.isEqual(pt2))
- return 0;// overlap case
-
- int vert10 = m_bunchEdgeCenterPoints.get(index1);
- Point2D pt10 = new Point2D();
- m_shape.getXY(vert10, pt10);
-
- int vert20 = m_bunchEdgeCenterPoints.get(index2);
- Point2D pt20 = new Point2D();
- m_shape.getXY(vert20, pt20);
- // _ASSERT(pt10.isEqual(pt20));
-
- Point2D v1 = new Point2D();
- v1.sub(pt1, pt10);
- Point2D v2 = new Point2D();
- v2.sub(pt2, pt20);
- int result = Point2D._compareVectors(v1, v2);
- return result;
- }
}
diff --git a/src/main/java/com/esri/core/geometry/SizeOf.java b/src/main/java/com/esri/core/geometry/SizeOf.java
new file mode 100644
index 00000000..8d9f4c77
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/SizeOf.java
@@ -0,0 +1,144 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
+import static sun.misc.Unsafe.ARRAY_CHAR_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_CHAR_INDEX_SCALE;
+import static sun.misc.Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+import static sun.misc.Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+import static sun.misc.Unsafe.ARRAY_INT_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_INT_INDEX_SCALE;
+import static sun.misc.Unsafe.ARRAY_LONG_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_LONG_INDEX_SCALE;
+import static sun.misc.Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+import static sun.misc.Unsafe.ARRAY_SHORT_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_SHORT_INDEX_SCALE;
+
+public final class SizeOf {
+ public static final int SIZE_OF_ATTRIBUTE_STREAM_OF_FLOAT = 24;
+
+ public static final int SIZE_OF_ATTRIBUTE_STREAM_OF_DBL = 24;
+
+ public static final int SIZE_OF_ATTRIBUTE_STREAM_OF_INT8 = 24;
+
+ public static final int SIZE_OF_ATTRIBUTE_STREAM_OF_INT16 = 24;
+
+ public static final int SIZE_OF_ATTRIBUTE_STREAM_OF_INT32 = 24;
+
+ public static final int SIZE_OF_ATTRIBUTE_STREAM_OF_INT64 = 24;
+
+ public static final int SIZE_OF_ENVELOPE = 32;
+
+ public static final int SIZE_OF_ENVELOPE2D = 48;
+
+ public static final int SIZE_OF_LINE = 56;
+
+ public static final int SIZE_OF_MULTI_PATH = 24;
+
+ public static final int SIZE_OF_MULTI_PATH_IMPL = 112;
+
+ public static final int SIZE_OF_MULTI_POINT = 24;
+
+ public static final int SIZE_OF_MULTI_POINT_IMPL = 56;
+
+ public static final int SIZE_OF_POINT = 40;
+
+ public static final int SIZE_OF_POLYGON = 24;
+
+ public static final int SIZE_OF_POLYLINE = 24;
+
+ public static final int SIZE_OF_OGC_CONCRETE_GEOMETRY_COLLECTION = 24;
+
+ public static final int SIZE_OF_OGC_LINE_STRING = 24;
+
+ public static final int SIZE_OF_OGC_MULTI_LINE_STRING = 24;
+
+ public static final int SIZE_OF_OGC_MULTI_POINT = 24;
+
+ public static final int SIZE_OF_OGC_MULTI_POLYGON = 24;
+
+ public static final int SIZE_OF_OGC_POINT = 24;
+
+ public static final int SIZE_OF_OGC_POLYGON = 24;
+
+ public static final int SIZE_OF_MAPGEOMETRY = 24;
+
+ public static final int SIZE_OF_RASTERIZED_GEOMETRY_2D_IMPL = 112;
+
+ public static final int SIZE_OF_SCAN_CALLBACK_IMPL = 32;
+
+ public static final int SIZE_OF_TRANSFORMATION_2D = 64;
+
+ public static final int SIZE_OF_SIMPLE_RASTERIZER = 64;
+
+ public static final int SIZE_OF_EDGE = 48;
+
+ public static final int SIZE_OF_QUAD_TREE_IMPL = 48;
+
+ public static final int SIZE_OF_DATA = 24;
+
+ public static final int SIZE_OF_STRIDED_INDEX_TYPE_COLLECTION = 48;
+
+ public static long sizeOfByteArray(int length) {
+ return ARRAY_BYTE_BASE_OFFSET + (((long) ARRAY_BYTE_INDEX_SCALE) * length);
+ }
+
+ public static long sizeOfShortArray(int length) {
+ return ARRAY_SHORT_BASE_OFFSET + (((long) ARRAY_SHORT_INDEX_SCALE) * length);
+ }
+
+ public static long sizeOfCharArray(int length) {
+ return ARRAY_CHAR_BASE_OFFSET + (((long) ARRAY_CHAR_INDEX_SCALE) * length);
+ }
+
+ public static long sizeOfIntArray(int length) {
+ return ARRAY_INT_BASE_OFFSET + (((long) ARRAY_INT_INDEX_SCALE) * length);
+ }
+
+ public static long sizeOfLongArray(int length) {
+ return ARRAY_LONG_BASE_OFFSET + (((long) ARRAY_LONG_INDEX_SCALE) * length);
+ }
+
+ public static long sizeOfFloatArray(int length) {
+ return ARRAY_FLOAT_BASE_OFFSET + (((long) ARRAY_FLOAT_INDEX_SCALE) * length);
+ }
+
+ public static long sizeOfDoubleArray(int length) {
+ return ARRAY_DOUBLE_BASE_OFFSET + (((long) ARRAY_DOUBLE_INDEX_SCALE) * length);
+ }
+
+ public static long sizeOfObjectArray(int length)
+ {
+ return ARRAY_OBJECT_BASE_OFFSET + (((long) ARRAY_OBJECT_INDEX_SCALE) * length);
+ }
+
+ private SizeOf() {
+ }
+}
diff --git a/src/com/esri/core/geometry/SpatialReference.java b/src/main/java/com/esri/core/geometry/SpatialReference.java
similarity index 66%
rename from src/com/esri/core/geometry/SpatialReference.java
rename to src/main/java/com/esri/core/geometry/SpatialReference.java
index c2621096..4c337e27 100644
--- a/src/com/esri/core/geometry/SpatialReference.java
+++ b/src/main/java/com/esri/core/geometry/SpatialReference.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,13 +24,10 @@
package com.esri.core.geometry;
+import com.fasterxml.jackson.core.JsonParser;
+
import java.io.ObjectStreamException;
import java.io.Serializable;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-
-import com.esri.core.geometry.SpatialReferenceSerializer;
-import com.esri.core.geometry.VertexDescription;
/**
* A class that represents the spatial reference for the geometry.
@@ -87,48 +84,91 @@ boolean isLocal() {
* if parsing has failed
*/
public static SpatialReference fromJson(JsonParser parser) throws Exception {
- int wkid = 0;
+ return fromJson(new JsonParserReader(parser));
+ }
+
+ public static SpatialReference fromJson(String string) throws Exception {
+ return fromJson(JsonParserReader.createFromString(string));
+ }
+
+ public static SpatialReference fromJson(JsonReader parser) throws Exception {
+ // Note this class is processed specially: it is expected that the
+ // iterator points to the first element of the SR object.
+ boolean bFoundWkid = false;
+ boolean bFoundLatestWkid = false;
+ boolean bFoundVcsWkid = false;
+ boolean bFoundLatestVcsWkid = false;
+ boolean bFoundWkt = false;
+
+ int wkid = -1;
+ int latestWkid = -1;
+ int vcs_wkid = -1;
+ int latestVcsWkid = -1;
String wkt = null;
- if (!JSONUtils.isObjectStart(parser))
- return null;
-
- while (parser.nextToken() != JsonToken.END_OBJECT) {
- String fieldName = parser.getCurrentName();
+ while (parser.nextToken() != JsonReader.Token.END_OBJECT) {
+ String name = parser.currentString();
parser.nextToken();
- if (parser.getCurrentToken() == JsonToken.VALUE_NULL) {
- continue;
+
+ if (!bFoundWkid && name.equals("wkid")) {
+ bFoundWkid = true;
+
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
+ wkid = parser.currentIntValue();
+ } else if (!bFoundLatestWkid && name.equals("latestWkid")) {
+ bFoundLatestWkid = true;
+
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
+ latestWkid = parser.currentIntValue();
+ } else if (!bFoundWkt && name.equals("wkt")) {
+ bFoundWkt = true;
+
+ if (parser.currentToken() == JsonReader.Token.VALUE_STRING)
+ wkt = parser.currentString();
+ } else if (!bFoundVcsWkid && name.equals("vcsWkid")) {
+ bFoundVcsWkid = true;
+
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
+ vcs_wkid = parser.currentIntValue();
+ } else if (!bFoundLatestVcsWkid && name.equals("latestVcsWkid")) {
+ bFoundLatestVcsWkid = true;
+
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
+ latestVcsWkid = parser.currentIntValue();
}
+ }
+
+ if (latestVcsWkid <= 0 && vcs_wkid > 0) {
+ latestVcsWkid = vcs_wkid;
+ }
+
+ // iter.step_out_after(); do not step out for the spatial reference,
+ // because this method is used standalone
- if ("latestWkid".equals(fieldName)) {// get wkid
- wkid = parser.getIntValue();
- } else if ("wkid".equals(fieldName)) {// get wkid
- wkid = parser.getIntValue();
- } else if ("wkt".equals(fieldName)) {
- wkt = parser.getText();
- } else {
- parser.skipChildren();
+ SpatialReference spatial_reference = null;
+
+ if (wkt != null && wkt.length() != 0) {
+ try {
+ spatial_reference = SpatialReference.create(wkt);
+ } catch (Exception e) {
}
}
- // END _OBJECT
- if (wkid > 0) // 1. Try to use wkid
- {
+ if (spatial_reference == null && latestWkid > 0) {
try {
- return SpatialReference.create(wkid);
- } catch (IllegalArgumentException ex) {
- // if (wkt == null || wkt.length() == 0) //Here this will be our
- // default.
- // throw ex;
+ spatial_reference = SpatialReference.create(latestWkid);
+ } catch (Exception e) {
}
}
- if (wkt != null && wkt.length() != 0) // try to use wkt.
- {
- return SpatialReference.create(wkt);
+ if (spatial_reference == null && wkid > 0) {
+ try {
+ spatial_reference = SpatialReference.create(wkid);
+ } catch (Exception e) {
+ }
}
- return null;
- }
+ return spatial_reference;
+ }
/**
* Returns the well known ID for the horizontal coordinate system of the
diff --git a/src/com/esri/core/geometry/SpatialReferenceImpl.java b/src/main/java/com/esri/core/geometry/SpatialReferenceImpl.java
similarity index 66%
rename from src/com/esri/core/geometry/SpatialReferenceImpl.java
rename to src/main/java/com/esri/core/geometry/SpatialReferenceImpl.java
index 6a7540a5..25158369 100644
--- a/src/com/esri/core/geometry/SpatialReferenceImpl.java
+++ b/src/main/java/com/esri/core/geometry/SpatialReferenceImpl.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,26 +24,13 @@
package com.esri.core.geometry;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Arrays;
import java.util.concurrent.locks.ReentrantLock;
-import java.lang.ref.*;
-
-import com.esri.core.geometry.Envelope2D;
-import com.esri.core.geometry.GeoDist;
-import com.esri.core.geometry.GeometryException;
-import com.esri.core.geometry.PeDouble;
-import com.esri.core.geometry.Point;
-import com.esri.core.geometry.Polyline;
-import com.esri.core.geometry.SpatialReference;
-import com.esri.core.geometry.SpatialReferenceImpl;
-import com.esri.core.geometry.VertexDescription.Semantics;
-
class SpatialReferenceImpl extends SpatialReference {
- static boolean no_projection_engine = true;
- public static int c_SULIMIT32 = 2147483645;
- public static long c_SULIMIT64 = 9007199254740990L;
+ static final boolean no_projection_engine = true;
+ public final static int c_SULIMIT32 = 2147483645;
+ public final static long c_SULIMIT64 = 9007199254740990L;
enum Precision {
Integer32, Integer64, FloatingPoint
@@ -126,7 +113,7 @@ public void queryValidCoordinateRange(Envelope2D env2D) {
break;
default:
// TODO
- throw new GeometryException("internal error");// fixme
+ throw GeometryException.GeometryInternalError();
}
env2D.setCoords(getFalseX(), getFalseY(), getFalseX() + delta,
@@ -218,7 +205,7 @@ public boolean equals(Object obj) {
return false;
if (m_userWkid == 0) {
- if (!m_userWkt.equals(m_userWkt))// m_userWkt cannot be null here!
+ if (!m_userWkt.equals(sr.m_userWkt))// m_userWkt cannot be null here!
return false;
}
@@ -230,10 +217,77 @@ static double geodesicDistanceOnWGS84Impl(Point ptFrom, Point ptTo) {
double e2 = 0.0066943799901413165; // ellipticity for WGS_1984
double rpu = Math.PI / 180.0;
PeDouble answer = new PeDouble();
- GeoDist.geodesic_distance_ngs(a, e2, ptFrom.getXY().x * rpu,
- ptFrom.getXY().y * rpu, ptTo.getXY().x * rpu, ptTo.getXY().y
+ GeoDist.geodesic_distance_ngs(a, e2, ptFrom.getX() * rpu,
+ ptFrom.getY() * rpu, ptTo.getX() * rpu, ptTo.getY()
* rpu, answer, null, null);
return answer.val;
}
+ public String getAuthority() {
+ int latestWKID = getLatestID();
+ if (latestWKID <= 0)
+ return new String("");
+
+ return getAuthority_(latestWKID);
+ }
+
+ private String getAuthority_(int latestWKID) {
+ String authority;
+
+ if (latestWKID >= 1024 && latestWKID <= 32767) {
+
+ int index = Arrays.binarySearch(m_esri_codes, latestWKID);
+
+ if (index >= 0)
+ authority = new String("ESRI");
+ else
+ authority = new String("EPSG");
+ } else {
+ authority = new String("ESRI");
+ }
+
+ return authority;
+ }
+
+ private static final int[] m_esri_codes = {
+ 2181, // ED_1950_Turkey_9
+ 2182, // ED_1950_Turkey_10
+ 2183, // ED_1950_Turkey_11
+ 2184, // ED_1950_Turkey_12
+ 2185, // ED_1950_Turkey_13
+ 2186, // ED_1950_Turkey_14
+ 2187, // ED_1950_Turkey_15
+ 4305, // GCS_Voirol_Unifie_1960
+ 4812, // GCS_Voirol_Unifie_1960_Paris
+ 20002, // Pulkovo_1995_GK_Zone_2
+ 20003, // Pulkovo_1995_GK_Zone_3
+ 20062, // Pulkovo_1995_GK_Zone_2N
+ 20063, // Pulkovo_1995_GK_Zone_3N
+ 24721, // La_Canoa_UTM_Zone_21N
+ 26761, // NAD_1927_StatePlane_Hawaii_1_FIPS_5101
+ 26762, // NAD_1927_StatePlane_Hawaii_2_FIPS_5102
+ 26763, // NAD_1927_StatePlane_Hawaii_3_FIPS_5103
+ 26764, // NAD_1927_StatePlane_Hawaii_4_FIPS_5104
+ 26765, // NAD_1927_StatePlane_Hawaii_5_FIPS_5105
+ 26788, // NAD_1927_StatePlane_Michigan_North_FIPS_2111
+ 26789, // NAD_1927_StatePlane_Michigan_Central_FIPS_2112
+ 26790, // NAD_1927_StatePlane_Michigan_South_FIPS_2113
+ 30591, // Nord_Algerie
+ 30592, // Sud_Algerie
+ 31491, // Germany_Zone_1
+ 31492, // Germany_Zone_2
+ 31493, // Germany_Zone_3
+ 31494, // Germany_Zone_4
+ 31495, // Germany_Zone_5
+ 32059, // NAD_1927_StatePlane_Puerto_Rico_FIPS_5201
+ 32060, // NAD_1927_StatePlane_Virgin_Islands_St_Croix_FIPS_5202
+ };
+
+ @Override
+ public int hashCode() {
+ if (m_userWkid != 0)
+ return NumberUtils.hash(m_userWkid);
+
+ return m_userWkt.hashCode();
+ }
}
diff --git a/src/com/esri/core/geometry/SpatialReferenceSerializer.java b/src/main/java/com/esri/core/geometry/SpatialReferenceSerializer.java
similarity index 98%
rename from src/com/esri/core/geometry/SpatialReferenceSerializer.java
rename to src/main/java/com/esri/core/geometry/SpatialReferenceSerializer.java
index 5df978f2..0cf25e6c 100644
--- a/src/com/esri/core/geometry/SpatialReferenceSerializer.java
+++ b/src/main/java/com/esri/core/geometry/SpatialReferenceSerializer.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/StridedIndexTypeCollection.java b/src/main/java/com/esri/core/geometry/StridedIndexTypeCollection.java
similarity index 55%
rename from src/com/esri/core/geometry/StridedIndexTypeCollection.java
rename to src/main/java/com/esri/core/geometry/StridedIndexTypeCollection.java
index 90bfc9d5..ae1f4dca 100644
--- a/src/com/esri/core/geometry/StridedIndexTypeCollection.java
+++ b/src/main/java/com/esri/core/geometry/StridedIndexTypeCollection.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2018 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,7 +23,11 @@
*/
package com.esri.core.geometry;
-import java.util.ArrayList;
+import java.io.Serializable;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_STRIDED_INDEX_TYPE_COLLECTION;
+import static com.esri.core.geometry.SizeOf.sizeOfIntArray;
+import static com.esri.core.geometry.SizeOf.sizeOfObjectArray;
/**
* A collection of strides of Index_type elements. To be used when one needs a
@@ -31,40 +35,53 @@
* structs with Index_type members) Recycles the strides. Allows for constant
* time creation and deletion of an element.
*/
-final class StridedIndexTypeCollection {
-
- private int m_firstFree;
- private int m_last;
+final class StridedIndexTypeCollection implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private int[][] m_buffer = null;
+ private int m_firstFree = -1;
+ private int m_last = 0;
+ private int m_size = 0;
+ private int m_capacity = 0;
+ private int m_bufferSize = 0;
private int m_stride;
private int m_realStride;
- private int m_realBlockSize;
private int m_blockSize;
- private int m_blockMask;
- private int m_blockPower;
- private int m_size;
- private int m_capacity;
- private ArrayList m_buffer;
+
+ /*
+ private final static int m_realBlockSize = 2048;//if you change this, change m_blockSize, m_blockPower, m_blockMask, and st_sizes
+ private final static int m_blockMask = 0x7FF;
+ private final static int m_blockPower = 11;
+ private final static int[] st_sizes = {16, 32, 64, 128, 256, 512, 1024, 2048};
+ */
+
+ private final static int m_realBlockSize = 16384;// if you change this,
+ // change m_blockSize,
+ // m_blockPower,
+ // m_blockMask, and
+ // st_sizes
+ private final static int m_blockMask = 0x3FFF;
+ private final static int m_blockPower = 14;
+ private final static int[] st_sizes = { 16, 32, 64, 128, 256, 512, 1024,
+ 2048, 4096, 8192, 16384 };
StridedIndexTypeCollection(int stride) {
- m_firstFree = -1;
- m_last = 0;
- m_size = 0;
m_stride = stride;
m_realStride = stride;
- m_realBlockSize = 2048;//if you change this, change m_blockSize, m_blockPower, m_blockMask, and st_sizes
- m_blockPower = 11;
- m_blockMask = 0x7FF;
- m_blockSize = 2048 / m_realStride;
- m_capacity = 0;
- m_buffer = null;
+ m_blockSize = m_realBlockSize / m_realStride;
}
+ private boolean dbgdelete_(int element) {
+ m_buffer[element >> m_blockPower][(element & m_blockMask) + 1] = -0x7eadbeed;
+ return true;
+ }
+
void deleteElement(int element) {
- assert dbgdelete_(element);
+ assert(dbgdelete_(element));
int totalStrides = (element >> m_blockPower) * m_blockSize
* m_realStride + (element & m_blockMask);
if (totalStrides < m_last * m_realStride) {
- m_buffer.get(element >> m_blockPower)[element & m_blockMask] = m_firstFree;
+ m_buffer[element >> m_blockPower][element & m_blockMask] = m_firstFree;
m_firstFree = element;
} else {
assert (totalStrides == m_last * m_realStride);
@@ -75,13 +92,15 @@ void deleteElement(int element) {
// Returns the given field of the element.
int getField(int element, int field) {
- return m_buffer.get(element >> m_blockPower)[(element & m_blockMask)
+ assert(m_buffer[element >> m_blockPower][(element & m_blockMask) + 1] != -0x7eadbeed);
+ return m_buffer[element >> m_blockPower][(element & m_blockMask)
+ field];
}
// Sets the given field of the element.
void setField(int element, int field, int value) {
- m_buffer.get(element >> m_blockPower)[(element & m_blockMask) + field] = value;
+ assert(m_buffer[element >> m_blockPower][(element & m_blockMask) + 1] != -0x7eadbeed);
+ m_buffer[element >> m_blockPower][(element & m_blockMask) + field] = value;
}
// Returns the stride size
@@ -95,19 +114,28 @@ int newElement() {
int element = m_firstFree;
if (element == -1) {
if (m_last == m_capacity) {
- grow_(m_capacity != 0 ? ((m_capacity + 1) * 3 / 2) : 1);
+ long newcap = m_capacity != 0 ? (((long) m_capacity + 1) * 3 / 2)
+ : (long) 1;
+ if (newcap > Integer.MAX_VALUE)
+ newcap = Integer.MAX_VALUE;// cannot grow past 2gb elements
+ // presently
+
+ if (newcap == m_capacity)
+ throw new IndexOutOfBoundsException();
+
+ grow_(newcap);
}
element = ((m_last / m_blockSize) << m_blockPower)
+ (m_last % m_blockSize) * m_realStride;
m_last++;
} else {
- m_firstFree = m_buffer.get(element >> m_blockPower)[element
+ m_firstFree = m_buffer[element >> m_blockPower][element
& m_blockMask];
}
m_size++;
- int ar[] = m_buffer.get(element >> m_blockPower);
+ int ar[] = m_buffer[element >> m_blockPower];
int ind = element & m_blockMask;
for (int i = 0; i < m_stride; i++) {
ar[ind + i] = -1;
@@ -150,8 +178,8 @@ int capacity() {
// Swaps content of two elements (each field of the stride)
void swap(int element1, int element2) {
- int ar1[] = m_buffer.get(element1 >> m_blockPower);
- int ar2[] = m_buffer.get(element2 >> m_blockPower);
+ int ar1[] = m_buffer[element1 >> m_blockPower];
+ int ar2[] = m_buffer[element2 >> m_blockPower];
int ind1 = element1 & m_blockMask;
int ind2 = element2 & m_blockMask;
for (int i = 0; i < m_stride; i++) {
@@ -163,8 +191,8 @@ void swap(int element1, int element2) {
// Swaps content of two fields
void swapField(int element1, int element2, int field) {
- int ar1[] = m_buffer.get(element1 >> m_blockPower);
- int ar2[] = m_buffer.get(element2 >> m_blockPower);
+ int ar1[] = m_buffer[element1 >> m_blockPower];
+ int ar2[] = m_buffer[element2 >> m_blockPower];
int ind1 = (element1 & m_blockMask) + field;
int ind2 = (element2 & m_blockMask) + field;
int tmp = ar1[ind1];
@@ -188,60 +216,83 @@ static boolean isValidElement(int element) {
return element >= 0;
}
- private boolean dbgdelete_(int element) {
- setField(element, 1, 0x7eadbeed);
- return true;
- }
+ private void ensureBufferBlocksCapacity(int blocks) {
+ if (m_buffer.length < blocks) {
+ int[][] newBuffer = new int[blocks][];
+ for (int i = 0; i < m_buffer.length; i++) {
+ newBuffer[i] = m_buffer[i];
+ }
- final static int[] st_sizes = {16, 32, 64, 128, 256, 512, 1024, 2048};
+ m_buffer = newBuffer;
+ }
+ }
- private void grow_(int newsize) {
+ private void grow_(long newsize) {
if (m_buffer == null) {
- m_buffer = new ArrayList();
+ m_bufferSize = 0;
+ m_buffer = new int[8][];
}
assert (newsize > m_capacity);
- int nblocks = (newsize + m_blockSize - 1) / m_blockSize;
- m_buffer.ensureCapacity(nblocks);
+ long nblocks = (newsize + m_blockSize - 1) / m_blockSize;
+ if (nblocks > Integer.MAX_VALUE)
+ throw new IndexOutOfBoundsException();
+
+ ensureBufferBlocksCapacity((int) nblocks);
if (nblocks == 1) {
// When less than one block is needed we allocate smaller arrays
// than m_realBlockSize to avoid initialization cost.
int oldsz = m_capacity > 0 ? m_capacity : 0;
assert (oldsz < newsize);
int i = 0;
- int realnewsize = newsize * m_realStride;
+ int realnewsize = (int) newsize * m_realStride;
while (realnewsize > st_sizes[i])
// get the size to allocate. Using fixed sizes to reduce
// fragmentation.
i++;
int[] b = new int[st_sizes[i]];
- if (m_buffer.size() == 1) {
- System.arraycopy(m_buffer.get(0), 0, b, 0, m_size
- * m_realStride);
- m_buffer.set(0, b);
+ if (m_bufferSize == 1) {
+ System.arraycopy(m_buffer[0], 0, b, 0, m_buffer[0].length);
+ m_buffer[0] = b;
} else {
- m_buffer.add(b);
+ m_buffer[m_bufferSize] = b;
+ m_bufferSize++;
}
m_capacity = b.length / m_realStride;
} else {
- if (m_buffer.size() == 1) {
- if (m_buffer.get(0).length < m_realBlockSize) {
+ if (nblocks * m_blockSize > Integer.MAX_VALUE)
+ throw new IndexOutOfBoundsException();
+
+ if (m_bufferSize == 1) {
+ if (m_buffer[0].length < m_realBlockSize) {
// resize the first buffer to ensure it is equal the
// m_realBlockSize.
int[] b = new int[m_realBlockSize];
- System.arraycopy(m_buffer.get(0), 0, b, 0, m_size
- * m_realStride);
- m_buffer.set(0, b);
+ System.arraycopy(m_buffer[0], 0, b, 0, m_buffer[0].length);
+ m_buffer[0] = b;
m_capacity = m_blockSize;
}
}
- while (m_buffer.size() < nblocks) {
- m_buffer.add(new int[m_realBlockSize]);
+ while (m_bufferSize < nblocks) {
+ m_buffer[m_bufferSize++] = new int[m_realBlockSize];
m_capacity += m_blockSize;
}
}
}
+ public long estimateMemorySize()
+ {
+ long size = SIZE_OF_STRIDED_INDEX_TYPE_COLLECTION;
+ if (m_buffer != null) {
+ size += sizeOfObjectArray(m_buffer.length);
+ for (int i = 0; i< m_buffer.length; i++) {
+ if (m_buffer[i] != null) {
+ size += sizeOfIntArray(m_buffer[i].length);
+ }
+ }
+ }
+ return size;
+ }
}
diff --git a/src/main/java/com/esri/core/geometry/StringUtils.java b/src/main/java/com/esri/core/geometry/StringUtils.java
new file mode 100644
index 00000000..3237e13c
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/StringUtils.java
@@ -0,0 +1,110 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+import java.util.Locale;
+
+class StringUtils {
+
+ static void appendDouble(double value, int precision,
+ StringBuilder stringBuilder) {
+ if (precision < 0) {
+ precision = 0;
+ } else if (precision > 17) {
+ precision = 17;
+ }
+
+ String format = "%." + precision + "g";
+
+ String str_dbl = String.format(Locale.US, format, value);
+
+ boolean b_found_dot = false;
+ boolean b_found_exponent = false;
+
+ for (int i = 0; i < str_dbl.length(); i++) {
+ char c = str_dbl.charAt(i);
+
+ if (c == '.') {
+ b_found_dot = true;
+ } else if (c == 'e' || c == 'E') {
+ b_found_exponent = true;
+ break;
+ }
+ }
+
+ if (b_found_dot && !b_found_exponent) {
+ StringBuilder buffer = removeTrailingZeros_(str_dbl);
+ stringBuilder.append(buffer);
+ } else {
+ stringBuilder.append(str_dbl);
+ }
+ }
+
+ static void appendDoubleF(double value, int decimals,
+ StringBuilder stringBuilder) {
+ if (decimals < 0) {
+ decimals = 0;
+ } else if (decimals > 17) {
+ decimals = 17;
+ }
+
+ String format = "%." + decimals + "f";
+
+ String str_dbl = String.format(Locale.US, format, value);
+
+ boolean b_found_dot = false;
+
+ for (int i = 0; i < str_dbl.length(); i++) {
+ char c = str_dbl.charAt(i);
+
+ if (c == '.') {
+ b_found_dot = true;
+ break;
+ }
+ }
+
+ if (b_found_dot) {
+ StringBuilder buffer = removeTrailingZeros_(str_dbl);
+ stringBuilder.append(buffer);
+ } else {
+ stringBuilder.append(str_dbl);
+ }
+ }
+
+ static private StringBuilder removeTrailingZeros_(String str_dbl) {
+ StringBuilder buffer = new StringBuilder(str_dbl);
+ int non_zero = buffer.length() - 1;
+
+ while (buffer.charAt(non_zero) == '0') {
+ non_zero--;
+ }
+
+ buffer.delete(non_zero + 1, buffer.length());
+
+ if (buffer.charAt(non_zero) == '.') {
+ buffer.deleteCharAt(non_zero);
+ }
+
+ return buffer;
+ }
+}
diff --git a/src/com/esri/core/geometry/SweepComparator.java b/src/main/java/com/esri/core/geometry/SweepComparator.java
similarity index 99%
rename from src/com/esri/core/geometry/SweepComparator.java
rename to src/main/java/com/esri/core/geometry/SweepComparator.java
index 9fb76798..a1f94376 100644
--- a/src/com/esri/core/geometry/SweepComparator.java
+++ b/src/main/java/com/esri/core/geometry/SweepComparator.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/SweepMonkierComparator.java b/src/main/java/com/esri/core/geometry/SweepMonkierComparator.java
similarity index 99%
rename from src/com/esri/core/geometry/SweepMonkierComparator.java
rename to src/main/java/com/esri/core/geometry/SweepMonkierComparator.java
index 6589ef64..2edeef22 100644
--- a/src/com/esri/core/geometry/SweepMonkierComparator.java
+++ b/src/main/java/com/esri/core/geometry/SweepMonkierComparator.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/TopoGraph.java b/src/main/java/com/esri/core/geometry/TopoGraph.java
similarity index 79%
rename from src/com/esri/core/geometry/TopoGraph.java
rename to src/main/java/com/esri/core/geometry/TopoGraph.java
index e7a40cfa..5f57251c 100644
--- a/src/com/esri/core/geometry/TopoGraph.java
+++ b/src/main/java/com/esri/core/geometry/TopoGraph.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ static interface EnumInputMode {
final static int enumInputModeBuildGraph = 0;
final static int enumInputModeSimplifyAlternate = 4 + 0;
final static int enumInputModeSimplifyWinding = 4 + 1;
- final static int enumInputModeSimplifyForBuffer = 4 + 2;
+ final static int enumInputModeIsSimplePolygon = 4 + 3;
}
EditShape m_shape;
@@ -64,6 +64,24 @@ static interface EnumInputMode {
int m_halfEdgeIndex; // vertex index of half-edges in the m_shape
int m_tmpHalfEdgeParentageIndex;
int m_tmpHalfEdgeWindingNumberIndex;
+ int m_tmpHalfEdgeOddEvenNumberIndex = -1;
+
+ int m_universe_geomID = -1;
+
+ boolean m_buildChains = true;
+
+ private boolean m_dirty_check_failed = false;
+ private double m_check_dirty_planesweep_tolerance = Double.NaN;
+
+ void check_dirty_planesweep(double tolerance) {
+ m_check_dirty_planesweep_tolerance = tolerance;
+ }
+
+ boolean dirty_check_failed() {
+ return m_dirty_check_failed;
+ }
+
+ NonSimpleResult m_non_simple_result = new NonSimpleResult();
int m_pointCount;// point count processed in this Topo_graph. Used to
// reserve data.
@@ -554,15 +572,6 @@ void planeSweepParentage_(int inputMode, ProgressTracker progress_tracker) {
int attachedTreeNode = getHalfEdgeUserIndex(
clusterHalfEdge, treeNodeIndex);
if (attachedTreeNode == -1) {
- // #ifdef DEBUG
- // //Debug-checking that the "from" is below the
- // "to"
- // Point_2D pt_1;
- // getHalfEdgeFromXY(clusterHalfEdge, pt_1);
- // Point_2D pt_2;
- // getHalfEdgeToXY(clusterHalfEdge, pt_2);
- // assert(pt_1.compare(pt_2) < 0);
- // #endif
int newTreeNode = aet.addElement(clusterHalfEdge,
-1);
new_edges.add(newTreeNode);
@@ -701,160 +710,214 @@ void planeSweepParentagePropagateParentage_(Treap aet, int treeNode,
assert (parentChain != -1);
- // Now do specific sweep calculations
if (inputMode == EnumInputMode.enumInputModeBuildGraph) {
- int chainParentage = getChainParentage(edgeChain);
+ propagate_parentage_build_graph_(aet, treeNode, edge, leftEdge, edgeChain, edgeChainParent, twinHalfEdgeChain);
+ }
+ else if (inputMode == EnumInputMode.enumInputModeSimplifyWinding) {
+ propagate_parentage_winding_(aet, treeNode, edge, leftEdge, twinEdge, edgeChain, edgeChainParent, twinHalfEdgeChain);
+ }
+ else if (inputMode == EnumInputMode.enumInputModeSimplifyAlternate) {
+ propagate_parentage_alternate_(aet, treeNode, edge, leftEdge, twinEdge, edgeChain, edgeChainParent, twinHalfEdgeChain);
+ }
+
+ }
+
+ void propagate_parentage_build_graph_(Treap aet, int treeNode, int edge, int leftEdge,
+ int edgeChain, int edgeChainParent, int twinHalfEdgeChain) {
+ // Now do specific sweep calculations
+ int chainParentage = getChainParentage(edgeChain);
- if (leftEdge != -1) {
- // borrow the parentage from the left edge also
- int leftEdgeChain = getHalfEdgeChain(leftEdge);
- // dbg_print_edge_(edge);
- // dbg_print_edge_(leftEdge);
-
- // We take parentage from the left edge (that edge has been
- // already processed), and move its face parentage accross this
- // edge/twin pair.
- // While the parentage is moved, accross, any bits of the
- // parentage that is present in the twin are removed, because
- // the twin is the right edge of the current face.
- // The remaining bits are added to the face parentage of this
- // edge, indicating that the face this edge borders, belongs to
- // all the parents that are still active to the left.
- int twinChainParentage = getChainParentage(twinHalfEdgeChain);
- int leftChainParentage = getChainParentage(leftEdgeChain);
-
- int edgeParentage = getHalfEdgeParentage(edge);
- int spikeParentage = chainParentage & twinChainParentage
- & leftChainParentage; // parentage that needs to stay
- leftChainParentage = leftChainParentage
+ if (leftEdge != -1) {
+ // borrow the parentage from the left edge also
+ int leftEdgeChain = getHalfEdgeChain(leftEdge);
+
+ // We take parentage from the left edge (that edge has been
+ // already processed), and move its face parentage accross this
+ // edge/twin pair.
+ // While the parentage is moved, accross, any bits of the
+ // parentage that is present in the twin are removed, because
+ // the twin is the right edge of the current face.
+ // The remaining bits are added to the face parentage of this
+ // edge, indicating that the face this edge borders, belongs to
+ // all the parents that are still active to the left.
+ int twinChainParentage = getChainParentage(twinHalfEdgeChain);
+ int leftChainParentage = getChainParentage(leftEdgeChain);
+
+ int edgeParentage = getHalfEdgeParentage(edge);
+ int spikeParentage = chainParentage & twinChainParentage
+ & leftChainParentage; // parentage that needs to stay
+ leftChainParentage = leftChainParentage
^ (leftChainParentage & edgeParentage);
- leftChainParentage |= spikeParentage;
- // leftChainParentage = leftChainParentage ^ (leftChainParentage
- // & twinChainParentage);//only parentage that is abscent in the
- // twin is propagated to the right
- // leftChainParentage = leftChainParentage ^ (leftChainParentage
- // & edgeParentage);//only parentage that is abscent in the twin
- // is propagated to the right
- // & (and) leaves the parentage that is common for left edge and
- // the twin, while ^ (xor) leaves the parentage that is present
- // in the
- // left edge only.
-
- if (leftChainParentage != 0) {
- // propagate left parentage to the current edge and its
- // twin.
- setChainParentage_(twinHalfEdgeChain, twinChainParentage
+ leftChainParentage |= spikeParentage;
+
+ if (leftChainParentage != 0) {
+ // propagate left parentage to the current edge and its
+ // twin.
+ setChainParentage_(twinHalfEdgeChain, twinChainParentage
| leftChainParentage);
- setChainParentage_(edgeChain, leftChainParentage
+ setChainParentage_(edgeChain, leftChainParentage
| chainParentage);
- chainParentage |= leftChainParentage;
- }
+ chainParentage |= leftChainParentage;
+ }
// dbg_print_edge_(edge);
- }
+ }
- for (int rightNode = aet.getNext(treeNode); rightNode != -1; rightNode = aet
+ for (int rightNode = aet.getNext(treeNode); rightNode != -1; rightNode = aet
.getNext(rightNode)) {
- int rightEdge = aet.getElement(rightNode);
- int rightTwin = getHalfEdgeTwin(rightEdge);
- // dbg_print_edge_(rightEdge);
- int rightTwinChain = getHalfEdgeChain(rightTwin);
- int rightTwinChainParentage = getChainParentage(rightTwinChain);
- int rightEdgeParentage = getHalfEdgeParentage(rightEdge);
- int rightEdgeChain = getHalfEdgeChain(rightEdge);
- int rightChainParentage = getChainParentage(rightEdgeChain);
-
- int spikeParentage = rightTwinChainParentage
- & rightChainParentage & chainParentage; // parentage
- // that needs to
- // stay
- chainParentage = chainParentage
- ^ (chainParentage & rightEdgeParentage);// only
- // parentage
- // that is
- // abscent in
- // the twin is
- // propagated to
- // the right
- chainParentage |= spikeParentage;
-
- if (chainParentage == 0)
- break;
-
- setChainParentage_(rightTwinChain, rightTwinChainParentage
+ int rightEdge = aet.getElement(rightNode);
+ int rightTwin = getHalfEdgeTwin(rightEdge);
+
+ int rightTwinChain = getHalfEdgeChain(rightTwin);
+ int rightTwinChainParentage = getChainParentage(rightTwinChain);
+ int rightEdgeParentage = getHalfEdgeParentage(rightEdge);
+ int rightEdgeChain = getHalfEdgeChain(rightEdge);
+ int rightChainParentage = getChainParentage(rightEdgeChain);
+
+ int spikeParentage = rightTwinChainParentage
+ & rightChainParentage & chainParentage; // parentage
+ // that needs to
+ // stay
+ chainParentage = chainParentage
+ ^ (chainParentage & rightEdgeParentage);// only
+ // parentage
+ // that is
+ // abscent in
+ // the twin is
+ // propagated to
+ // the right
+ chainParentage |= spikeParentage;
+
+ if (chainParentage == 0)
+ break;
+
+ setChainParentage_(rightTwinChain, rightTwinChainParentage
| chainParentage);
- setChainParentage_(rightEdgeChain, rightChainParentage
+ setChainParentage_(rightEdgeChain, rightChainParentage
| chainParentage);
- // dbg_print_edge_(rightEdge);
- }
}
+ }
- if (inputMode == EnumInputMode.enumInputModeSimplifyWinding) {
- if (edgeChain == twinHalfEdgeChain)
- return;
- // starting from the left most edge, calculate winding.
- int edgeWinding = getHalfEdgeUserIndex(edge,
- m_tmpHalfEdgeWindingNumberIndex);
- edgeWinding += getHalfEdgeUserIndex(twinEdge,
- m_tmpHalfEdgeWindingNumberIndex);
- int winding = 0;
- AttributeStreamOfInt32 chainStack = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 windingStack = new AttributeStreamOfInt32(0);
- windingStack.add(0);
- for (int leftNode = aet.getFirst(-1); leftNode != treeNode; leftNode = aet
+ void propagate_parentage_winding_(Treap aet, int treeNode, int edge, int leftEdge, int twinEdge,
+ int edgeChain, int edgeChainParent, int twinHalfEdgeChain) {
+
+ if (edgeChain == twinHalfEdgeChain)
+ return;
+ // starting from the left most edge, calculate winding.
+ int edgeWinding = getHalfEdgeUserIndex(edge,
+ m_tmpHalfEdgeWindingNumberIndex);
+ edgeWinding += getHalfEdgeUserIndex(twinEdge,
+ m_tmpHalfEdgeWindingNumberIndex);
+ int winding = 0;
+ AttributeStreamOfInt32 chainStack = new AttributeStreamOfInt32(0);
+ AttributeStreamOfInt32 windingStack = new AttributeStreamOfInt32(0);
+ windingStack.add(0);
+ for (int leftNode = aet.getFirst(-1); leftNode != treeNode; leftNode = aet
.getNext(leftNode)) {
- int leftEdge1 = aet.getElement(leftNode);
- int leftTwin = getHalfEdgeTwin(leftEdge1);
- int l_chain = getHalfEdgeChain(leftEdge1);
- int lt_chain = getHalfEdgeChain(leftTwin);
-
- if (l_chain != lt_chain) {
- int leftWinding = getHalfEdgeUserIndex(leftEdge1,
- m_tmpHalfEdgeWindingNumberIndex);
- leftWinding += getHalfEdgeUserIndex(leftTwin,
- m_tmpHalfEdgeWindingNumberIndex);
- winding += leftWinding;
-
- boolean popped = false;
- if (chainStack.size() != 0
- && chainStack.getLast() == lt_chain) {
- windingStack
- .resizePreserveCapacity(windingStack.size() - 1);
- chainStack
- .resizePreserveCapacity(chainStack.size() - 1);
- popped = true;
- }
+ int leftEdge1 = aet.getElement(leftNode);
+ int leftTwin = getHalfEdgeTwin(leftEdge1);
+ int l_chain = getHalfEdgeChain(leftEdge1);
+ int lt_chain = getHalfEdgeChain(leftTwin);
+
+ if (l_chain != lt_chain) {
+ int leftWinding = getHalfEdgeUserIndex(leftEdge1,
+ m_tmpHalfEdgeWindingNumberIndex);
+ leftWinding += getHalfEdgeUserIndex(leftTwin,
+ m_tmpHalfEdgeWindingNumberIndex);
+ winding += leftWinding;
+
+ boolean popped = false;
+ if (chainStack.size() != 0
+ && chainStack.getLast() == lt_chain) {
+ windingStack.removeLast();
+ chainStack.removeLast();
+ popped = true;
+ }
- // geometry_release_assert(getChainParent(lt_chain) != -1);
+ if (getChainParent(lt_chain) == -1)
+ throw GeometryException.GeometryInternalError();
- if (!popped || getChainParent(lt_chain) != l_chain) {
- windingStack.add(winding);
- chainStack.add(l_chain);
- }
+ if (!popped || getChainParent(lt_chain) != l_chain) {
+ windingStack.add(winding);
+ chainStack.add(l_chain);
}
}
+ }
- winding += edgeWinding;
+ winding += edgeWinding;
- if (chainStack.size() != 0
+ if (chainStack.size() != 0
&& chainStack.getLast() == twinHalfEdgeChain) {
- windingStack.resizePreserveCapacity(windingStack.size() - 1);
- chainStack.resizePreserveCapacity(chainStack.size() - 1);
+ windingStack.removeLast();
+ chainStack.removeLast();
+ }
+
+ if (winding != 0) {
+ if (windingStack.getLast() == 0) {
+ int geometry = m_shape.getFirstGeometry();
+ int geometryID = getGeometryID(geometry);
+ setChainParentage_(edgeChain, geometryID);
}
+ } else {
+ if (windingStack.getLast() != 0) {
+ int geometry = m_shape.getFirstGeometry();
+ int geometryID = getGeometryID(geometry);
+ setChainParentage_(edgeChain, geometryID);
+ }
+ }
+ }
+
+ void propagate_parentage_alternate_(Treap aet, int treeNode, int edge,
+ int leftEdge, int twinEdge, int edgeChain, int edgeChainParent,
+ int twinHalfEdgeChain) {
+ // Now do specific sweep calculations
+ // This one is done when we are doing a topological operation.
+ int geometry = m_shape.getFirstGeometry();
+ int geometryID = getGeometryID(geometry);
+
+ if (leftEdge == -1) {
+ // no left edge neighbour means the twin chain is surrounded by the
+ // universe
+ assert (getChainParent(twinHalfEdgeChain) == m_universeChain);
+ assert (getChainParentage(twinHalfEdgeChain) == 0 || getChainParentage(twinHalfEdgeChain) == m_universe_geomID);
+ assert (getChainParentage(edgeChain) == 0);
+ setChainParentage_(twinHalfEdgeChain, m_universe_geomID);
+ int parity = getHalfEdgeUserIndex(edge,
+ m_tmpHalfEdgeOddEvenNumberIndex);
+ if ((parity & 1) != 0)
+ setChainParentage_(edgeChain, geometryID);// set the parenentage
+ // from the parity
+ else
+ setChainParentage_(edgeChain, m_universe_geomID);// this chain
+ // does not
+ // belong to
+ // geometry
+ } else {
+ int twin_parentage = getChainParentage(twinHalfEdgeChain);
+ if (twin_parentage == 0) {
+ int leftEdgeChain = getHalfEdgeChain(leftEdge);
+ int left_parentage = getChainParentage(leftEdgeChain);
+ setChainParentage_(twinHalfEdgeChain, left_parentage);
+ int parity = getHalfEdgeUserIndex(edge,
+ m_tmpHalfEdgeOddEvenNumberIndex);
+ if ((parity & 1) != 0)
+ setChainParentage_(edgeChain,
+ (left_parentage == geometryID) ? m_universe_geomID
+ : geometryID);
+ else
+ setChainParentage_(edgeChain, left_parentage);
- if (winding != 0) {
- if (windingStack.read(windingStack.size() - 1) == 0) {
- int geometry = m_shape.getFirstGeometry();
- int geometryID = getGeometryID(geometry);
- setChainParentage_(edgeChain, geometryID);
- }
} else {
- if (windingStack.read(windingStack.size() - 1) != 0) {
- int geometry = m_shape.getFirstGeometry();
- int geometryID = getGeometryID(geometry);
- setChainParentage_(edgeChain, geometryID);
- }
+ int parity = getHalfEdgeUserIndex(edge,
+ m_tmpHalfEdgeOddEvenNumberIndex);
+ if ((parity & 1) != 0)
+ setChainParentage_(edgeChain,
+ (twin_parentage == geometryID) ? m_universe_geomID
+ : geometryID);
+ else
+ setChainParentage_(edgeChain, twin_parentage);
}
+
}
}
@@ -901,13 +964,10 @@ boolean trySetChainParentFromTwin_(int chainToSet, int twinChain) {
double twinArea = getChainArea(twinChain);
assert (twinArea != 0);
if (area > 0 && twinArea < 0) {
- // assert(twinArea + area <= area * Number_utils::double_eps() *
- // 100);
setChainParent_(chainToSet, twinChain);
return true;
}
if (area < 0 && twinArea > 0) {
- // assert(-area <= twinArea);
setChainParent_(chainToSet, twinChain);
return true;
} else {
@@ -941,9 +1001,16 @@ void createHalfEdges_(int inputMode, AttributeStreamOfInt32 sorted_vertices) {
int clusterTo = m_shape.getUserIndex(next, m_clusterIndex);
assert (clusterTo != -1);
- assert (cluster != clusterTo);// probably will assert for
- // verticasl segments! Need to
- // refactor a little
+ if (cluster == clusterTo) {
+ if (m_shape.getSegment(vertex) != null) {
+ assert (m_shape.getSegment(vertex).calculateLength2D() == 0);
+ } else {
+ assert (m_shape.getXY(vertex).isEqual(m_shape.getXY(next)));
+ }
+
+ continue;
+ }
+
int half_edge = newHalfEdgePair_();
int twinEdge = getHalfEdgeTwin(half_edge);
@@ -1056,7 +1123,24 @@ void createHalfEdges_(int inputMode, AttributeStreamOfInt32 sorted_vertices) {
m_tmpHalfEdgeWindingNumberIndex, windingNumber);
setHalfEdgeUserIndex(twinEdge,
m_tmpHalfEdgeWindingNumberIndex, windingNumberTwin);
+ } else if (inputMode == EnumInputMode.enumInputModeIsSimplePolygon) {
+ setHalfEdgeUserIndex(twinEdge, m_tmpHalfEdgeParentageIndex,
+ m_universe_geomID);
+ setHalfEdgeUserIndex(half_edge,
+ m_tmpHalfEdgeParentageIndex,
+ gt == Geometry.GeometryType.Polygon ? geometryID
+ : 0);
+ } else if (inputMode == EnumInputMode.enumInputModeSimplifyAlternate) {
+ setHalfEdgeUserIndex(twinEdge, m_tmpHalfEdgeParentageIndex,
+ 0);
+ setHalfEdgeUserIndex(half_edge,
+ m_tmpHalfEdgeParentageIndex, 0);
+ setHalfEdgeUserIndex(half_edge,
+ m_tmpHalfEdgeOddEvenNumberIndex, 1);
+ setHalfEdgeUserIndex(twinEdge,
+ m_tmpHalfEdgeOddEvenNumberIndex, 1);
}
+
int edgeBit = gt == Geometry.GeometryType.Polygon ? c_edgeBitMask
: 0;
setHalfEdgeParentage_(half_edge, geometryID | edgeBit);
@@ -1095,12 +1179,13 @@ void mergeVertexListsOfEdges_(int eDst, int eSrc) {
void sortHalfEdgesByAngle_(int inputMode) {
AttributeStreamOfInt32 angleSorter = new AttributeStreamOfInt32(0);
angleSorter.reserve(10);
+ TopoGraphAngleComparer tgac = new TopoGraphAngleComparer(this);
// Now go through the clusters, sort edges in each cluster by angle, and
// reconnect the halfedges of sorted edges in the sorted order.
// Also share the parentage information between coinciding edges and
// remove duplicates.
for (int cluster = getFirstCluster(); cluster != -1; cluster = getNextCluster(cluster)) {
- angleSorter.resizePreserveCapacity(0);
+ angleSorter.clear(false);
int first = getClusterHalfEdge(cluster);
if (first != -1) {
// 1. sort edges originating at the cluster by angle (counter -
@@ -1115,21 +1200,26 @@ void sortHalfEdgesByAngle_(int inputMode) {
} while (edge != first);
if (angleSorter.size() > 1) {
+ boolean changed_order = true;
if (angleSorter.size() > 2) {
angleSorter.Sort(0, angleSorter.size(),
- new TopoGraphAngleComparer(this)); // std::sort(angleSorter.get_ptr(),
+ tgac); // std::sort(angleSorter.get_ptr(),
// angleSorter.get_ptr()
// +
// angleSorter.size(),
// TopoGraphAngleComparer(this));
angleSorter.add(angleSorter.get(0));
} else {
- if (compareEdgeAngles_(angleSorter.get(0),
+ //no need to sort most two edge cases. we only need to make sure that edges going up are sorted
+ if (compareEdgeAnglesForPair_(angleSorter.get(0),
angleSorter.get(1)) > 0) {
int tmp = angleSorter.get(0);
angleSorter.set(0, angleSorter.get(1));
angleSorter.set(1, tmp);
}
+ else {
+ changed_order = false;
+ }
}
// 2. get rid of duplicate edges by merging them (duplicate
// edges appear at this step because we converted all
@@ -1224,12 +1314,31 @@ void sortHalfEdgesByAngle_(int inputMode) {
// even number of edges coinciding there and
// half of them has opposite direction to
// another half.
+ } else if (inputMode == EnumInputMode.enumInputModeIsSimplePolygon) {
+ m_non_simple_result = new NonSimpleResult(NonSimpleResult.Reason.CrossOver, cluster, -1);
+ return;
+ }
+ else if (m_tmpHalfEdgeOddEvenNumberIndex != -1) {
+ int newHalfEdgeWinding = getHalfEdgeUserIndex(
+ ePrev, m_tmpHalfEdgeOddEvenNumberIndex)
+ + getHalfEdgeUserIndex(e,
+ m_tmpHalfEdgeOddEvenNumberIndex);
+ int newTwinEdgeWinding = getHalfEdgeUserIndex(
+ ePrevTwin,
+ m_tmpHalfEdgeOddEvenNumberIndex)
+ + getHalfEdgeUserIndex(eTwin,
+ m_tmpHalfEdgeOddEvenNumberIndex);
+ setHalfEdgeUserIndex(ePrev,
+ m_tmpHalfEdgeOddEvenNumberIndex,
+ newHalfEdgeWinding);
+ setHalfEdgeUserIndex(ePrevTwin,
+ m_tmpHalfEdgeOddEvenNumberIndex,
+ newTwinEdgeWinding);
}
mergeVertexListsOfEdges_(ePrev, e);
deleteEdgeImpl_(e);
- assert (n < 3 || e0 == angleSorter.read(angleSorter
- .size() - 1));
+ assert (n < 3 || e0 == angleSorter.getLast());
prevMerged = ePrev;
angleSorter.set(i, -1);
if (e == e0) {
@@ -1239,7 +1348,10 @@ void sortHalfEdgesByAngle_(int inputMode) {
continue;
}
-
+ else {
+ //edges do not coincide
+ }
+
updateVertexToHalfEdgeConnection_(prevMerged, false);
prevMerged = -1;
ePrev = e;
@@ -1247,8 +1359,27 @@ void sortHalfEdgesByAngle_(int inputMode) {
ePrevTwin = eTwin;
}
+
updateVertexToHalfEdgeConnection_(prevMerged, false);
prevMerged = -1;
+
+ if (!changed_order) {
+ //small optimization to avoid reconnecting if nothing changed
+ e0 = -1;
+ for (int i = 0, n = angleSorter.size(); i < n; i++) {
+ int e = angleSorter.get(i);
+ if (e == -1)
+ continue;
+ e0 = e;
+ break;
+ }
+
+ if (first != e0)
+ setClusterHalfEdge_(cluster, e0);
+
+ continue; //next cluster
+ }
+
// 3. Reconnect edges in the sorted order. The edges are
// sorted counter clockwise.
@@ -1284,6 +1415,18 @@ void sortHalfEdgesByAngle_(int inputMode) {
ePrev = e;
ePrevTo = eTo;
ePrevTwin = eTwin;
+ if (inputMode == EnumInputMode.enumInputModeIsSimplePolygon)
+ {
+ int par1 = getHalfEdgeUserIndex(e, m_tmpHalfEdgeParentageIndex) |
+ getHalfEdgeUserIndex(getHalfEdgePrev(e), m_tmpHalfEdgeParentageIndex);
+ if (par1 == (m_universe_geomID | 1))
+ {
+ //violation of face parentage
+ m_non_simple_result = new NonSimpleResult(NonSimpleResult.Reason.CrossOver, cluster, -1);
+ return;
+ }
+ }
+
}
setClusterHalfEdge_(cluster, e0);// smallest angle goes
@@ -1293,7 +1436,7 @@ void sortHalfEdgesByAngle_(int inputMode) {
}
}
- void buildChains_() {
+ void buildChains_(int inputMode) {
// Creates chains and puts them in the list of chains.
// Does not set the chain parentage
// Does not connect chains
@@ -1347,15 +1490,10 @@ void buildChains_() {
// visited.
e = getHalfEdgeNext(e);
} while (e != edge);
+
+ assert(inputMode != EnumInputMode.enumInputModeIsSimplePolygon || parentage != (1 | m_universe_geomID));
+
setChainParentage_(chain, parentage);
-
- // Polygon::SPtr poly =
- // dbg_dump_chain_to_polygon_(chain);
- // char buf[1024];
- // sprintf(buf, "c:\\temp\\chain%d.txt",
- // m_chain_data->size());
- // Operator_factory_local::SaveGeometryToInternalTextFile(buf,
- // poly);
}
edge = getHalfEdgeNext(getHalfEdgeTwin(edge));// next
@@ -1394,7 +1532,6 @@ void buildChains_() {
}
void simplify_(int inputMode) {
- assert (inputMode != EnumInputMode.enumInputModeBuildGraph);
if (inputMode == EnumInputMode.enumInputModeSimplifyAlternate) {
simplifyAlternate_();
} else if (inputMode == EnumInputMode.enumInputModeSimplifyWinding) {
@@ -1403,80 +1540,98 @@ void simplify_(int inputMode) {
}
void simplifyAlternate_() {
- int geometry = m_shape.getFirstGeometry();
- int geometryID = getGeometryID(geometry);
+ //there is nothing to do
+ }
- int universe_chain = getFirstChain(); // winding = 0;
- simplifyAlternateRecursion_(universe_chain, geometryID, false);
+ void simplifyWinding_() {
+ //there is nothing to do
}
- void simplifyAlternateRecursion_(int parent_chain, int geometryID,
- boolean bEven) {
- boolean bEven_ = !bEven;
- for (int chain = getChainFirstIsland(parent_chain); chain != -1; chain = getChainNextInParent(chain)) {
- if (bEven_)
- setChainParentage_(chain, geometryID);
- else
- setChainParentage_(chain, 0);
+ private int getFirstUnvisitedHalfEdgeOnCluster_(int cluster, int hintEdge,
+ int vistiedEdgesIndex) {
+ // finds first half edge which is unvisited (index is not set to 1.
+ // when hintEdge != -1, it is used to start going around the edges.
- simplifyAlternateRecursion_(chain, geometryID, bEven_);
- }
- }
+ int edge = hintEdge != -1 ? hintEdge : getClusterHalfEdge(cluster);
+ if (edge == -1)
+ return -1;
- void simplifyWinding_() {
- // there is nothing to do.
- }
+ int f = edge;
- boolean removeSpikes_() {
- boolean bRemoved = false;
- for (int chain = getFirstChain(); chain != -1;) {
- int firstHalfEdge = getChainHalfEdge(chain);
- assert (firstHalfEdge != -1);
+ while (true) {
+ int v = getHalfEdgeUserIndex(edge, vistiedEdgesIndex);
+ if (v != 1) {
+ return edge;
+ }
+
+ int next = getHalfEdgeNext(getHalfEdgeTwin(edge));
+ if (next == f)
+ return -1;
- boolean bRemovedEdge = false;
+ edge = next;
+ }
+ }
- int prev = getHalfEdgePrev(firstHalfEdge);
- int half_edge = firstHalfEdge;
+ boolean removeSpikes_() {
+ boolean removed = false;
+ int visitedIndex = createUserIndexForHalfEdges();
+ for (int cluster = getFirstCluster(); cluster != -1; cluster = getNextCluster(cluster)) {
+ int nextClusterEdge = -1; //a hint
while (true) {
- int twin = getHalfEdgeTwin(half_edge);
- if (prev == twin) {
- int next2 = deleteEdgeInternal_(half_edge);
- bRemovedEdge = true;
- if (next2 == -1) {
- // The chain has been deleted.
- break;
- }
+ int firstHalfEdge = getFirstUnvisitedHalfEdgeOnCluster_(cluster, nextClusterEdge, visitedIndex);
+ if (firstHalfEdge == -1)
+ break;
+
+ nextClusterEdge = getHalfEdgeNext(getHalfEdgeTwin(firstHalfEdge));
+ int faceHalfEdge = firstHalfEdge;
+
+ while (true) {
+ int faceHalfEdgeNext = getHalfEdgeNext(faceHalfEdge);
+ int faceHalfEdgePrev = getHalfEdgePrev(faceHalfEdge);
+ int faceHalfEdgeTwin = getHalfEdgeTwin(faceHalfEdge);
+
+ if (faceHalfEdgePrev == faceHalfEdgeTwin) {
+ deleteEdgeInternal_(faceHalfEdge); //deletes the edge and its twin
+ removed = true;
+
+ if (nextClusterEdge == faceHalfEdge || nextClusterEdge == faceHalfEdgeTwin)
+ nextClusterEdge = -1; //deleted the hint edge
+
+ if (faceHalfEdge == firstHalfEdge || faceHalfEdgePrev == firstHalfEdge) {
+ firstHalfEdge = faceHalfEdgeNext;
+ if (faceHalfEdge == firstHalfEdge || faceHalfEdgePrev == firstHalfEdge) {
+ //deleted all edges in a face
+ break;
+ }
+
+ faceHalfEdge = faceHalfEdgeNext;
+ continue;
+ }
- if (half_edge == firstHalfEdge) {
- firstHalfEdge = next2;
+ }
+ else {
+ setHalfEdgeUserIndex(faceHalfEdge, visitedIndex, 1);
}
- half_edge = next2;
- prev = getHalfEdgePrev(half_edge);
- } else {
- prev = half_edge;
- half_edge = getHalfEdgeNext(half_edge);
- if (half_edge == firstHalfEdge)
+ faceHalfEdge = faceHalfEdgeNext;
+ if (faceHalfEdge == firstHalfEdge)
break;
}
- }
- bRemoved |= bRemovedEdge;
- if (bRemovedEdge) {
- chain = deleteChain_(chain);
- } else
- chain = getChainNext(chain);
+ }
}
- return bRemoved;
+ return removed;
}
-
+
void setEditShapeImpl_(EditShape shape, int inputMode,
AttributeStreamOfInt32 editShapeGeometries,
- ProgressTracker progress_tracker) {
+ ProgressTracker progress_tracker, boolean bBuildChains) {
+ assert(!m_dirty_check_failed);
assert (editShapeGeometries == null || editShapeGeometries.size() > 0);
removeShape();
+ m_buildChains = bBuildChains;
assert (m_shape == null);
m_shape = shape;
m_geometryIDIndex = m_shape.createGeometryUserIndex();
@@ -1516,6 +1671,8 @@ void setEditShapeImpl_(EditShape shape, int inputMode,
geometry = m_shape.getNextGeometry(geometry);
}
}
+
+ m_universe_geomID = geomID;
m_pointCount = verticesSorter.size();
@@ -1531,8 +1688,7 @@ void setEditShapeImpl_(EditShape shape, int inputMode,
m_clusterVertices.setCapacity(m_pointCount);
- if ((progress_tracker != null) && !(progress_tracker.progress(-1, -1)))
- throw new UserCancelException();
+ ProgressTracker.checkAndThrow(progress_tracker);
m_clusterData.setCapacity(m_pointCount + 10);// 10 for some self
// intersections
@@ -1591,35 +1747,51 @@ void setEditShapeImpl_(EditShape shape, int inputMode,
ptFirst.setCoords(pt);
}
}
-
- if ((progress_tracker != null) && !(progress_tracker.progress(-1, -1)))
- throw new UserCancelException();
+
+ ProgressTracker.checkAndThrow(progress_tracker);
m_tmpHalfEdgeParentageIndex = createUserIndexForHalfEdges();
if (inputMode == EnumInputMode.enumInputModeSimplifyWinding) {
m_tmpHalfEdgeWindingNumberIndex = createUserIndexForHalfEdges();
}
+ if (inputMode == EnumInputMode.enumInputModeSimplifyAlternate) {
+ m_tmpHalfEdgeOddEvenNumberIndex = createUserIndexForHalfEdges();
+ }
+
createHalfEdges_(inputMode, verticesSorter);// For each geometry produce
// clusters and half edges
- // dbg_navigate_();
-
+ if (m_non_simple_result.m_reason != NonSimpleResult.Reason.NotDetermined)
+ return;
+
sortHalfEdgesByAngle_(inputMode);
+ if (m_non_simple_result.m_reason != NonSimpleResult.Reason.NotDetermined)
+ return;
+
+ if (!NumberUtils.isNaN(m_check_dirty_planesweep_tolerance)) {
+ if (!check_structure_after_dirty_sweep_())// checks the edges.
+ {
+ m_dirty_check_failed = true;// set m_dirty_check_failed when an
+ // issue is found. We'll rerun the
+ // planesweep using robust crack and
+ // cluster approach.
+ return;
+ }
+ }
- buildChains_();
+ buildChains_(inputMode);
+ if (m_non_simple_result.m_reason != NonSimpleResult.Reason.NotDetermined)
+ return;
deleteUserIndexForHalfEdges(m_tmpHalfEdgeParentageIndex);
m_tmpHalfEdgeParentageIndex = -1;
- planeSweepParentage_(inputMode, progress_tracker);
- // dbg_chk_chain_parents_();
+ if (m_buildChains)
+ planeSweepParentage_(inputMode, progress_tracker);
+
- if (inputMode != EnumInputMode.enumInputModeBuildGraph)
- simplify_(inputMode);
-
- // dbg_navigate_();
- // dbg_dump_chains_();
+ simplify_(inputMode);
}
void deleteEdgeImpl_(int half_edge) {
@@ -1704,32 +1876,26 @@ EditShape getShape() {
// calling this!
void setEditShape(EditShape shape, ProgressTracker progress_tracker) {
setEditShapeImpl_(shape, EnumInputMode.enumInputModeBuildGraph, null,
- progress_tracker);
+ progress_tracker, true);
}
- // Sets an edit shape and simplifies a geometry in it using "odd-even" rule.
- // This is the default simplify method for polygons.
- // The result edit shape contains a simple polygon.
- // The input shape could be a non-simple polygon or a polyline (polyline
- // need to form some rings to produce non-empty result).
- // The geometry has to be cracked and clustered before calling this!
- void setAndSimplifyEditShapeAlternate(EditShape shape, int geometry) {
+ void setEditShape(EditShape shape, ProgressTracker progress_tracker, boolean bBuildChains) {
+ setEditShapeImpl_(shape, EnumInputMode.enumInputModeBuildGraph, null,
+ progress_tracker, bBuildChains);
+ }
+
+ void setAndSimplifyEditShapeAlternate(EditShape shape, int geometry, ProgressTracker progressTracker) {
AttributeStreamOfInt32 geoms = new AttributeStreamOfInt32(0);
geoms.add(geometry);
setEditShapeImpl_(shape, EnumInputMode.enumInputModeSimplifyAlternate,
- geoms, null);
+ geoms, progressTracker, shape.getGeometryType(geometry) == Geometry.Type.Polygon.value());
}
- // Sets an edit shape and simplifies a geometry in it using "winding" rule.
- // The result edit shape contains a simple polygon.
- // The input shape could be a non-simple polygon or a polyline (polyline
- // need to form some rings to produce non-empty result).
- // The geometry has to be cracked and clustered before calling this!
- void setAndSimplifyEditShapeWinding(EditShape shape, int geometry) {
+ void setAndSimplifyEditShapeWinding(EditShape shape, int geometry, ProgressTracker progressTracker) {
AttributeStreamOfInt32 geoms = new AttributeStreamOfInt32(0);
geoms.add(geometry);
setEditShapeImpl_(shape, EnumInputMode.enumInputModeSimplifyWinding,
- geoms, null);
+ geoms, progressTracker, true);
}
// Removes shape from the topograph and removes any user index created on
@@ -1738,10 +1904,11 @@ void removeShape() {
if (m_shape == null)
return;
- if (m_geometryIDIndex != -1)
+ if (m_geometryIDIndex != -1) {
m_shape.removeGeometryUserIndex(m_geometryIDIndex);
+ m_geometryIDIndex = -1;
+ }
- m_geometryIDIndex = -1;
if (m_clusterIndex != -1) {
m_shape.removeUserIndex(m_clusterIndex);
m_clusterIndex = -1;
@@ -1762,6 +1929,11 @@ void removeShape() {
m_tmpHalfEdgeWindingNumberIndex = -1;
}
+ if (m_tmpHalfEdgeOddEvenNumberIndex != -1) {
+ deleteUserIndexForHalfEdges(m_tmpHalfEdgeOddEvenNumberIndex);
+ m_tmpHalfEdgeOddEvenNumberIndex = -1;
+ }
+
m_shape = null;
m_clusterData.deleteAll(true);
m_clusterVertices.deleteAll(true);
@@ -2010,7 +2182,9 @@ int deleteEdgeInternal_(int half_edge) {
setChainHalfEdge_(chain, n);
}
- if (!NumberUtils.isNaN(getChainArea(chain))) {
+ int chainIndex = getChainIndex_(chain);
+ double v = m_chainAreas.read(chainIndex);
+ if (!NumberUtils.isNaN(v)) {
setChainArea_(chain, NumberUtils.TheNaN);
setChainPerimeter_(chain, NumberUtils.TheNaN);
}
@@ -2338,13 +2512,6 @@ int compareEdgeAngles_(int edge1, int edge2) {
Point2D pt10 = new Point2D();
getHalfEdgeFromXY(edge1, pt10);
- // #ifdef DEBUG
- // {
- // Point_2D pt20;
- // get_half_edge_from_xy(edge2, pt20);
- // assert(pt10.is_equal(pt20));
- // }
- // #endif
Point2D v_1 = new Point2D();
v_1.sub(pt_1, pt10);
@@ -2353,4 +2520,99 @@ int compareEdgeAngles_(int edge1, int edge2) {
int result = Point2D._compareVectors(v_1, v_2);
return result;
}
+
+ int compareEdgeAnglesForPair_(int edge1, int edge2) {
+ if (edge1 == edge2)
+ return 0;
+
+ Point2D pt_1 = new Point2D();
+ getHalfEdgeToXY(edge1, pt_1);
+
+ Point2D pt_2 = new Point2D();
+ getHalfEdgeToXY(edge2, pt_2);
+
+ if (pt_1.isEqual(pt_2))
+ return 0;// overlap case
+
+ Point2D pt10 = new Point2D();
+ getHalfEdgeFromXY(edge1, pt10);
+
+ Point2D v_1 = new Point2D();
+ v_1.sub(pt_1, pt10);
+ Point2D v_2 = new Point2D();
+ v_2.sub(pt_2, pt10);
+
+ if (v_2.y >= 0 && v_1.y > 0) {
+ int result = Point2D._compareVectors(v_1, v_2);
+ return result;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ boolean check_structure_after_dirty_sweep_() {
+ // for each cluster go through the cluster half edges and check that
+ // min(edge1_length, edge2_length) * angle_between is less than
+ // m_check_dirty_planesweep_tolerance.
+ // Doing this helps us weed out cases missed by the dirty plane sweep.
+ // We do not need absolute accuracy here.
+ assert (!m_dirty_check_failed);
+ assert (!NumberUtils.isNaN(m_check_dirty_planesweep_tolerance));
+ double sqr_tol = MathUtils.sqr(m_check_dirty_planesweep_tolerance);
+ Point2D pt10 = new Point2D();
+ Point2D pt_2 = new Point2D();
+ Point2D pt_1 = new Point2D();
+ Point2D v_1 = new Point2D();
+ Point2D v_2 = new Point2D();
+ for (int cluster = getFirstCluster(); cluster != -1; cluster = getNextCluster(cluster)) {
+ int first = getClusterHalfEdge(cluster);
+ if (first != -1) {
+ int edge = first;
+ getHalfEdgeFromXY(edge, pt10);
+ getHalfEdgeToXY(edge, pt_2);
+ v_2.sub(pt_2, pt10);
+ double sqr_len2 = v_2.sqrLength();
+
+ do {
+ int prev = edge;
+ edge = getHalfEdgeNext(getHalfEdgeTwin(edge));
+
+ if (edge != prev) {
+ getHalfEdgeToXY(edge, pt_1);
+ assert (!pt_1.isEqual(pt_2));
+ v_1.sub(pt_1, pt10);
+ double sqr_len1 = v_1.sqrLength();
+
+ double cross = v_1.crossProduct(v_2); // cross_prod =
+ // len1 * len2 *
+ // sinA => sinA
+ // = cross_prod
+ // / (len1 *
+ // len2);
+ double sqr_sinA = (cross * cross)
+ / (sqr_len1 * sqr_len2); // sqr_sinA is
+ // approximately A^2
+ // especially for
+ // smaller angles
+ double sqr_dist = Math.min(sqr_len1, sqr_len2)
+ * sqr_sinA;
+ if (sqr_dist <= sqr_tol) {
+ // these edges incident on the cluster form a narrow
+ // wedge and thei require cracking event that was
+ // missed.
+ return false;
+ }
+
+ v_2.setCoords(v_1);
+ sqr_len2 = sqr_len1;
+ pt_2.setCoords(pt_1);
+ }
+ } while (edge != first);
+ }
+ }
+
+ return true;
+ }
+
}
diff --git a/src/com/esri/core/geometry/TopologicalOperations.java b/src/main/java/com/esri/core/geometry/TopologicalOperations.java
similarity index 87%
rename from src/com/esri/core/geometry/TopologicalOperations.java
rename to src/main/java/com/esri/core/geometry/TopologicalOperations.java
index 96fae909..def5cebe 100644
--- a/src/com/esri/core/geometry/TopologicalOperations.java
+++ b/src/main/java/com/esri/core/geometry/TopologicalOperations.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,7 +24,9 @@
package com.esri.core.geometry;
import com.esri.core.geometry.AttributeStreamOfInt32.IntComparator;
+import com.esri.core.geometry.Geometry.GeometryType;
import com.esri.core.geometry.MultiVertexGeometryImpl.GeometryXSimple;
+
import java.util.ArrayList;
final class TopologicalOperations {
@@ -33,6 +35,7 @@ final class TopologicalOperations {
Point2D m_dummy_pt_2 = new Point2D();
int m_from_edge_for_polylines;
boolean m_mask_lookup[] = null;
+ boolean m_bOGCOutput = false;
boolean isGoodParentage(int parentage) {
return parentage < m_mask_lookup.length ? m_mask_lookup[parentage]
@@ -51,7 +54,7 @@ void cut(int sideIndex, int cuttee, int cutter,
return;
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
static final class CompareCuts extends IntComparator {
@@ -79,22 +82,23 @@ public TopologicalOperations() {
m_from_edge_for_polylines = -1;
}
- void setEditShape(EditShape shape) {
+ void setEditShape(EditShape shape, ProgressTracker progressTracker) {
if (m_topo_graph == null)
m_topo_graph = new TopoGraph();
- m_topo_graph.setEditShape(shape, null);
+ m_topo_graph.setEditShape(shape, progressTracker);
}
void setEditShapeCrackAndCluster(EditShape shape, double tolerance,
ProgressTracker progressTracker) {
- CrackAndCluster.execute(shape, tolerance, progressTracker);
+ CrackAndCluster.execute(shape, tolerance, progressTracker, true);
for (int geometry = shape.getFirstGeometry(); geometry != -1; geometry = shape
.getNextGeometry(geometry)) {
if (shape.getGeometryType(geometry) == Geometry.Type.Polygon
.value())
- Simplificator.execute(shape, geometry, -1);
+ Simplificator.execute(shape, geometry, -1, m_bOGCOutput, progressTracker);
}
- setEditShape(shape);
+
+ setEditShape(shape, progressTracker);
}
private void collectPolygonPathsPreservingFrom_(int geometryFrom,
@@ -293,7 +297,7 @@ private int topoOperationPolygonPolygon_(int geometry_a, int geometry_b,
m_topo_graph.deleteUserIndexForHalfEdges(visitedEdges);
Simplificator.execute(shape, newGeometry,
- MultiVertexGeometryImpl.GeometryXSimple.Weak);
+ MultiVertexGeometryImpl.GeometryXSimple.Weak, m_bOGCOutput, null);
return newGeometry;
}
@@ -512,7 +516,7 @@ int[] topoOperationPolygonPolygonEx_(int geometry_a, int geometry_b,
m_topo_graph.deleteUserIndexForClusters(visitedClusters);
m_topo_graph.deleteUserIndexForHalfEdges(visitedEdges);
Simplificator.execute(shape, newGeometryPolygon,
- MultiVertexGeometryImpl.GeometryXSimple.Weak);
+ MultiVertexGeometryImpl.GeometryXSimple.Weak, m_bOGCOutput, null);
int[] result = new int[3];// always returns size 3 result.
result[0] = newGeometryMultipoint;
@@ -616,6 +620,7 @@ int tryMoveThroughCrossroadBackwards_(int half_edge) {
if (isGoodParentage(parentage)) {
if (goodEdge != -1)
return -1;
+
goodEdge = e;
}
@@ -671,19 +676,25 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
m_from_edge_for_polylines = -1;
int fromEdge = half_edge;
int toEdge = -1;
+ boolean b_found_impassable_crossroad = false;
+ int edgeCount = 1;
while (true) {
int halfEdgePrev = m_topo_graph.getHalfEdgePrev(half_edge);
if (halfEdgePrev == halfEdgeTwin)
break;// the end of a polyline
+
int halfEdgeTwinNext = m_topo_graph.getHalfEdgeNext(halfEdgeTwin);
if (m_topo_graph.getHalfEdgeTwin(halfEdgePrev) != halfEdgeTwinNext) {
// Crossroads is here. We can move through the crossroad only if
// there is only a single way to pass through.
+ //When doing planar_simplify we'll never go through the crossroad.
half_edge = tryMoveThroughCrossroadBackwards_(half_edge);
if (half_edge == -1)
break;
- else
+ else {
+ b_found_impassable_crossroad = true;
halfEdgeTwin = m_topo_graph.getHalfEdgeTwin(half_edge);
+ }
} else {
half_edge = halfEdgePrev;
halfEdgeTwin = halfEdgeTwinNext;
@@ -704,6 +715,7 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
m_topo_graph.setHalfEdgeUserIndex(halfEdgeTwin, visitedEdges, 1);
fromEdge = half_edge;
prevailingLength += prevailingDirection_(shape, half_edge);
+ edgeCount++;
}
if (toEdge == -1) {
@@ -714,14 +726,17 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
int halfEdgeNext = m_topo_graph.getHalfEdgeNext(half_edge);
if (halfEdgeNext == halfEdgeTwin)
break;
+
int halfEdgeTwinPrev = m_topo_graph
.getHalfEdgePrev(halfEdgeTwin);
if (m_topo_graph.getHalfEdgeTwin(halfEdgeNext) != halfEdgeTwinPrev) {
// Crossroads is here. We can move through the crossroad
// only if there is only a single way to pass through.
half_edge = tryMoveThroughCrossroadForward_(half_edge);
- if (half_edge == -1)
+ if (half_edge == -1) {
+ b_found_impassable_crossroad = true;
break;
+ }
else
halfEdgeTwin = m_topo_graph.getHalfEdgeTwin(half_edge);
} else {
@@ -738,14 +753,13 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
.setHalfEdgeUserIndex(halfEdgeTwin, visitedEdges, 1);
toEdge = half_edge;
prevailingLength += prevailingDirection_(shape, half_edge);
+ edgeCount++;
}
} else {
// toEdge has been found in the first while loop. This happens when
// we go around a face.
// Closed loops need special processing as we do not know where the
// polyline started or ended.
- // TODO: correctly process closed polylines (is_closed_path ==
- // true).
if (m_from_edge_for_polylines != -1) {
fromEdge = m_from_edge_for_polylines;
@@ -761,7 +775,7 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
// Crossroads is here. Pass through the crossroad.
toEdge = tryMoveThroughCrossroadBackwards_(fromEdge);
if (toEdge == -1)
- throw new GeometryException("internal error");// what?
+ throw GeometryException.GeometryInternalError();// what?
}
assert (isGoodParentage(getCombinedHalfEdgeParentage_(m_from_edge_for_polylines)));
@@ -782,12 +796,22 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
fromEdge = m_topo_graph.getHalfEdgeTwin(fromEdge);
assert (isGoodParentage(getCombinedHalfEdgeParentage_(fromEdge)));
}
+
int newPath = shape.insertPath(newGeometry, -1);// add new path at the
// end
half_edge = fromEdge;
int cluster = m_topo_graph.getHalfEdgeOrigin(fromEdge);
+ int clusterLast = m_topo_graph.getHalfEdgeTo(toEdge);
+ boolean b_closed = clusterLast == cluster;
+ // The linestrings can touch at boundary points only, while closed path
+ // has no boundary, therefore no other path can touch it.
+ // Therefore, if a closed path touches another path, we need to split
+ // the closed path in two to make the result OGC simple.
+ boolean b_closed_linestring_touches_other_linestring = b_closed
+ && b_found_impassable_crossroad;
+
int vert = selectVertex_(cluster, shape);
- assert (vert != -1);
+ assert(vert != -1);
int vertex_dominant = getVertexByID_(vert, geometry_dominant);
shape.addVertex(newPath, vertex_dominant);
@@ -795,25 +819,36 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
m_topo_graph.setClusterUserIndex(cluster, visitedClusters, 1);
}
+ int counter = 0;
+ int splitAt = b_closed_linestring_touches_other_linestring ? (edgeCount + 1) / 2 : -1;
while (true) {
int clusterTo = m_topo_graph.getHalfEdgeTo(half_edge);
int vert_1 = selectVertex_(clusterTo, shape);
vertex_dominant = getVertexByID_(vert_1, geometry_dominant);
shape.addVertex(newPath, vertex_dominant);
+ counter++;
if (visitedClusters != -1) {
m_topo_graph.setClusterUserIndex(clusterTo, visitedClusters, 1);
}
+ if (b_closed_linestring_touches_other_linestring
+ && counter == splitAt) {
+ newPath = shape.insertPath(newGeometry, -1);// add new path at
+ // the end
+ shape.addVertex(newPath, vertex_dominant);
+ }
+
assert (isGoodParentage(getCombinedHalfEdgeParentage_(half_edge)));
if (half_edge == toEdge)
break;
+
int halfEdgeNext = m_topo_graph.getHalfEdgeNext(half_edge);
if (m_topo_graph.getHalfEdgePrev(m_topo_graph
.getHalfEdgeTwin(half_edge)) != m_topo_graph
.getHalfEdgeTwin(halfEdgeNext)) {// crossroads.
half_edge = tryMoveThroughCrossroadForward_(half_edge);
if (half_edge == -1)
- throw new GeometryException("internal error");// a bug. This
+ throw GeometryException.GeometryInternalError();// a bug. This
// shoulf
// never
// happen
@@ -966,7 +1001,7 @@ static MultiPoint processMultiPointIntersectOrDiff_(MultiPoint multi_point,
boolean bFirstOut = true;
boolean bArea = (intersector.getDimension() == 2);
if (intersector.getDimension() != 1 && intersector.getDimension() != 2)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
for (int ipoints = 0; ipoints < npoints;) {
int num = multi_point.queryCoordinates(input_points, 1000, ipoints,
@@ -1034,7 +1069,7 @@ static Point processPointIntersectOrDiff_(Point point,
PolygonUtils.PiPResult[] test_results = new PolygonUtils.PiPResult[1];
boolean bArea = intersector.getDimension() == 2;
if (intersector.getDimension() != 1 && intersector.getDimension() != 2)
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
input_points[0] = point.getXY();
if (bArea)
PolygonUtils.testPointsInArea2D(intersector, input_points, 1,
@@ -1064,8 +1099,11 @@ static Point difference(Point point, Geometry geom, double tolerance) {
static Point intersection(Point point, Point point2, double tolerance) {
if (point.isEmpty() || point2.isEmpty())
return (Point) point.createInstance();
- if (Point2D.distance(point.getXY(), point2.getXY()) < tolerance) {
- return point;
+
+ if (CrackAndCluster.non_empty_points_need_to_cluster(tolerance, point,
+ point2)) {
+ return CrackAndCluster.cluster_non_empty_points(point, point2, 1,
+ 1, 1, 1);
}
return (Point) point.createInstance();
@@ -1076,7 +1114,9 @@ static Point difference(Point point, Point point2, double tolerance) {
return (Point) point.createInstance();
if (point2.isEmpty())
return point;
- if (Point2D.distance(point.getXY(), point2.getXY()) < tolerance) {
+
+ if (CrackAndCluster.non_empty_points_need_to_cluster(tolerance, point,
+ point2)) {
return (Point) point.createInstance();
}
@@ -1101,77 +1141,106 @@ MultiVertexGeometry planarSimplify(EditShape shape, int geom,
// This method will produce a polygon from a polyline when
// b_use_winding_rule_for_polygons is true. This is used by buffer.
m_topo_graph = new TopoGraph();
- if (dirty_result
- && shape.getGeometryType(geom) != Geometry.Type.MultiPoint
- .value()) {
- PlaneSweepCrackerHelper plane_sweeper = new PlaneSweepCrackerHelper();
- plane_sweeper.sweepVertical(shape, tolerance);
- if (plane_sweeper.hadCompications())// shame. The one pass
- // planesweep had some
- // complications. Need to do
- // full crack and cluster.
- {
- CrackAndCluster.execute(shape, tolerance, progress_tracker);
+ try
+ {
+ if (dirty_result
+ && shape.getGeometryType(geom) != Geometry.Type.MultiPoint
+ .value()) {
+ PlaneSweepCrackerHelper plane_sweeper = new PlaneSweepCrackerHelper();
+ plane_sweeper.sweepVertical(shape, tolerance);
+ if (plane_sweeper.hadCompications())// shame. The one pass
+ // planesweep had some
+ // complications. Need to do
+ // full crack and cluster.
+ {
+ CrackAndCluster.execute(shape, tolerance, progress_tracker, true);
+ dirty_result = false;
+ } else {
+ m_topo_graph.check_dirty_planesweep(tolerance);
+ }
+ } else {
+ CrackAndCluster.execute(shape, tolerance, progress_tracker, true);
+ dirty_result = false;
+ }
+
+ if (!b_use_winding_rule_for_polygons
+ || shape.getGeometryType(geom) == Geometry.Type.MultiPoint
+ .value())
+ m_topo_graph.setAndSimplifyEditShapeAlternate(shape, geom, progress_tracker);
+ else
+ m_topo_graph.setAndSimplifyEditShapeWinding(shape, geom, progress_tracker);
+
+ if (m_topo_graph.dirty_check_failed()) {
+ // we ran the sweep_vertical() before and it produced some
+ // issues that where detected by topo graph only.
+ assert (dirty_result);
+ m_topo_graph.removeShape();
+ m_topo_graph = null;
+ // that's at most two level recursion
+ return planarSimplify(shape, geom, tolerance,
+ b_use_winding_rule_for_polygons, false,
+ progress_tracker);
+ } else {
+ //can proceed
+ }
+
+ m_topo_graph.check_dirty_planesweep(NumberUtils.TheNaN);
+
+ int ID_a = m_topo_graph.getGeometryID(geom);
+ initMaskLookupArray_((ID_a) + 1);
+ m_mask_lookup[ID_a] = true; // Works only when there is a single
+ // geometry in the edit shape.
+ // To make it work when many geometries are present, this need to be
+ // modified.
+
+ if (shape.getGeometryType(geom) == Geometry.Type.Polygon.value()
+ || (b_use_winding_rule_for_polygons && shape
+ .getGeometryType(geom) != Geometry.Type.MultiPoint
+ .value())) {
+ // geom can be a polygon or a polyline.
+ // It can be a polyline only when the winding rule is true.
+ shape.setFillRule(geom, Polygon.FillRule.enumFillRuleOddEven);
+ int resGeom = topoOperationPolygonPolygon_(geom, -1, -1);
+
+ Polygon polygon = (Polygon) shape.getGeometry(resGeom);
+ polygon.setFillRule(Polygon.FillRule.enumFillRuleOddEven);//standardize the fill rule.
+ if (!dirty_result) {
+ ((MultiVertexGeometryImpl) polygon._getImpl()).setIsSimple(
+ GeometryXSimple.Strong, tolerance, false);
+ ((MultiPathImpl) polygon._getImpl())._updateOGCFlags();
+ } else
+ ((MultiVertexGeometryImpl) polygon._getImpl()).setIsSimple(
+ GeometryXSimple.Weak, 0.0, false);// dirty result means
+ // simple but with 0
+ // tolerance.
+
+ return polygon;
+ } else if (shape.getGeometryType(geom) == Geometry.Type.Polyline
+ .value()) {
+ int resGeom = topoOperationPolylinePolylineOrPolygon_(-1);
+
+ Polyline polyline = (Polyline) shape.getGeometry(resGeom);
+ if (!dirty_result)
+ ((MultiVertexGeometryImpl) polyline._getImpl()).setIsSimple(
+ GeometryXSimple.Strong, tolerance, false);
+
+ return polyline;
+ } else if (shape.getGeometryType(geom) == Geometry.Type.MultiPoint
+ .value()) {
+ int resGeom = topoOperationMultiPoint_();
+
+ MultiPoint mp = (MultiPoint) shape.getGeometry(resGeom);
+ if (!dirty_result)
+ ((MultiVertexGeometryImpl) mp._getImpl()).setIsSimple(
+ GeometryXSimple.Strong, tolerance, false);
+
+ return mp;
+ } else {
+ throw GeometryException.GeometryInternalError();
}
- } else {
- CrackAndCluster.execute(shape, tolerance, progress_tracker);
}
- if (!b_use_winding_rule_for_polygons
- || shape.getGeometryType(geom) == Geometry.Type.MultiPoint
- .value())
- m_topo_graph.setAndSimplifyEditShapeAlternate(shape, geom);
- else
- m_topo_graph.setAndSimplifyEditShapeWinding(shape, geom);
-
- int ID_a = m_topo_graph.getGeometryID(geom);
- initMaskLookupArray_((ID_a) + 1);
- m_mask_lookup[ID_a] = true; // Works only when there is a single
- // geometry in the edit shape.
- // To make it work when many geometries are present, this need to be
- // modified.
-
- if (shape.getGeometryType(geom) == Geometry.Type.Polygon.value()
- || (b_use_winding_rule_for_polygons && shape
- .getGeometryType(geom) != Geometry.Type.MultiPoint
- .value())) {
- // geom can be a polygon or a polyline.
- // It can be a polyline only when the winding rule is true.
- int resGeom = topoOperationPolygonPolygon_(geom, -1, -1);
-
- Polygon polygon = (Polygon) shape.getGeometry(resGeom);
- if (!dirty_result) {
- ((MultiVertexGeometryImpl) polygon._getImpl()).setIsSimple(
- GeometryXSimple.Strong, tolerance, false);
- ((MultiPathImpl) polygon._getImpl())._updateOGCFlags();
- } else
- ((MultiVertexGeometryImpl) polygon._getImpl()).setIsSimple(
- GeometryXSimple.Weak, 0.0, false);// dirty result means
- // simple but with 0
- // tolerance.
-
- return polygon;
- } else if (shape.getGeometryType(geom) == Geometry.Type.Polyline
- .value()) {
- int resGeom = topoOperationPolylinePolylineOrPolygon_(-1);
-
- Polyline polyline = (Polyline) shape.getGeometry(resGeom);
- if (!dirty_result)
- ((MultiVertexGeometryImpl) polyline._getImpl()).setIsSimple(
- GeometryXSimple.Strong, tolerance, false);
-
- return polyline;
- } else if (shape.getGeometryType(geom) == Geometry.Type.MultiPoint
- .value()) {
- int resGeom = topoOperationMultiPoint_();
-
- MultiPoint mp = (MultiPoint) shape.getGeometry(resGeom);
- if (!dirty_result)
- ((MultiVertexGeometryImpl) mp._getImpl()).setIsSimple(
- GeometryXSimple.Strong, tolerance, false);
-
- return mp;
- } else {
- throw new GeometryException("internal error");
+ finally {
+ m_topo_graph.removeShape();
}
}
@@ -1184,6 +1253,64 @@ static MultiVertexGeometry planarSimplify(MultiVertexGeometry input_geom,
use_winding_rule_for_polygons, dirty_result, progress_tracker);
}
+ boolean planarSimplifyNoCrackingAndCluster(boolean OGCoutput, EditShape shape, int geom, ProgressTracker progress_tracker)
+ {
+ m_bOGCOutput = OGCoutput;
+ m_topo_graph = new TopoGraph();
+ int rule = shape.getFillRule(geom);
+ int gt = shape.getGeometryType(geom);
+ if (rule != Polygon.FillRule.enumFillRuleWinding || gt == GeometryType.MultiPoint)
+ m_topo_graph.setAndSimplifyEditShapeAlternate(shape, geom, progress_tracker);
+ else
+ m_topo_graph.setAndSimplifyEditShapeWinding(shape, geom, progress_tracker);
+
+ if (m_topo_graph.dirty_check_failed())
+ return false;
+
+ m_topo_graph.check_dirty_planesweep(NumberUtils.TheNaN);
+
+ int ID_a = m_topo_graph.getGeometryID(geom);
+ initMaskLookupArray_((ID_a)+1);
+ m_mask_lookup[ID_a] = true; //Works only when there is a single geometry in the edit shape.
+ //To make it work when many geometries are present, this need to be modified.
+
+ if (shape.getGeometryType(geom) == GeometryType.Polygon || (rule == Polygon.FillRule.enumFillRuleWinding && shape.getGeometryType(geom) != GeometryType.MultiPoint))
+ {
+ //geom can be a polygon or a polyline.
+ //It can be a polyline only when the winding rule is true.
+ shape.setFillRule(geom, Polygon.FillRule.enumFillRuleOddEven);
+ int resGeom = topoOperationPolygonPolygon_(geom, -1, -1);
+ shape.swapGeometry(resGeom, geom);
+ shape.removeGeometry(resGeom);
+ }
+ else if (shape.getGeometryType(geom) == GeometryType.Polyline)
+ {
+ int resGeom = topoOperationPolylinePolylineOrPolygon_(-1);
+ shape.swapGeometry(resGeom, geom);
+ shape.removeGeometry(resGeom);
+ }
+ else if (shape.getGeometryType(geom) == GeometryType.MultiPoint)
+ {
+ int resGeom = topoOperationMultiPoint_();
+ shape.swapGeometry(resGeom, geom);
+ shape.removeGeometry(resGeom);
+ }
+ else
+ {
+ throw new GeometryException("internal error");
+ }
+
+ return true;
+ }
+
+
+ static MultiVertexGeometry simplifyOGC(MultiVertexGeometry input_geom, double tolerance, boolean dirty_result, ProgressTracker progress_tracker)
+ {
+ TopologicalOperations topoOps = new TopologicalOperations();
+ topoOps.m_bOGCOutput = true;
+ return topoOps.planarSimplifyImpl_(input_geom, tolerance, false, dirty_result, progress_tracker);
+ }
+
public int difference(int geometry_a, int geometry_b) {
int gtA = m_topo_graph.getShape().getGeometryType(geometry_a);
int gtB = m_topo_graph.getShape().getGeometryType(geometry_b);
@@ -1207,7 +1334,7 @@ public int difference(int geometry_a, int geometry_b) {
if (dim_a == 0)
return topoOperationMultiPoint_();
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
int dissolve(int geometry_a, int geometry_b) {
@@ -1239,7 +1366,7 @@ int dissolve(int geometry_a, int geometry_b) {
if (dim_a == 0 && dim_b == 0)
return topoOperationMultiPoint_();
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
public int intersection(int geometry_a, int geometry_b) {
@@ -1275,7 +1402,7 @@ public int intersection(int geometry_a, int geometry_b) {
// else
return topoOperationMultiPoint_();
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
int[] intersectionEx(int geometry_a, int geometry_b) {
@@ -1315,7 +1442,7 @@ int[] intersectionEx(int geometry_a, int geometry_b) {
return res;
}
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
public int symmetricDifference(int geometry_a, int geometry_b) {
@@ -1338,7 +1465,7 @@ public int symmetricDifference(int geometry_a, int geometry_b) {
if (dim_a == 0 && dim_b == 0)
return topoOperationMultiPoint_();
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
int extractShape(int geometry_in) {
@@ -1368,7 +1495,7 @@ int extractShape(int geometry_in) {
if (dim_a == 0)
return topoOperationMultiPoint_();
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
static Geometry normalizeInputGeometry_(Geometry geom) {
@@ -1550,7 +1677,7 @@ public static Geometry dissolve(Geometry geometry_a, Geometry geometry_b,
}
// break;
default:
- throw new GeometryException("internal error");
+ throw GeometryException.GeometryInternalError();
}
}
@@ -1635,12 +1762,26 @@ static Geometry dissolveDirty(ArrayList geometries,
public static Geometry intersection(Geometry geometry_a,
Geometry geometry_b, SpatialReference sr,
ProgressTracker progress_tracker) {
+
Envelope2D env2D_1 = new Envelope2D();
geometry_a.queryEnvelope2D(env2D_1);
Envelope2D env2D_2 = new Envelope2D();
geometry_b.queryEnvelope2D(env2D_2);
- if (!env2D_1.isIntersecting(env2D_2))// also includes the empty geometry
- // cases
+
+ Envelope2D envMerged = new Envelope2D();
+ envMerged.setCoords(env2D_1);
+ envMerged.merge(env2D_2);
+ double tolerance = InternalUtils.calculateToleranceFromGeometry(sr,
+ envMerged, true);// conservative to have same effect as simplify
+
+ Envelope2D e = new Envelope2D();
+ e.setCoords(env2D_2);
+ double tol_cluster = InternalUtils
+ .adjust_tolerance_for_TE_clustering(tolerance);
+ e.inflate(tol_cluster, tol_cluster);
+
+ if (!env2D_1.isIntersecting(e))// also includes the empty geometry
+ // cases
{
if (geometry_a.getDimension() <= geometry_b.getDimension())
return normalizeResult_(
@@ -1652,11 +1793,6 @@ public static Geometry intersection(Geometry geometry_a,
normalizeInputGeometry_(geometry_b.createInstance()),
geometry_a, geometry_b, '&');
}
- Envelope2D envMerged = new Envelope2D();
- envMerged.setCoords(env2D_1);
- envMerged.merge(env2D_2);
- double tolerance = InternalUtils.calculateToleranceFromGeometry(sr,
- envMerged, true);// conservative to have same effect as simplify
TopologicalOperations topoOps = new TopologicalOperations();
EditShape edit_shape = new EditShape();
@@ -1684,12 +1820,26 @@ public static Geometry intersection(Geometry geometry_a,
static Geometry[] intersectionEx(Geometry geometry_a, Geometry geometry_b,
SpatialReference sr, ProgressTracker progress_tracker) {
Geometry[] res_vec = new Geometry[3];
+
Envelope2D env2D_1 = new Envelope2D();
geometry_a.queryEnvelope2D(env2D_1);
Envelope2D env2D_2 = new Envelope2D();
geometry_b.queryEnvelope2D(env2D_2);
- if (!env2D_1.isIntersecting(env2D_2))// also includes the empty geometry
- // cases
+
+ Envelope2D envMerged = new Envelope2D();
+ envMerged.setCoords(env2D_1);
+ envMerged.merge(env2D_2);
+ double tolerance = InternalUtils.calculateToleranceFromGeometry(sr,
+ envMerged, true);// conservative to have same effect as simplify
+
+ Envelope2D e = new Envelope2D();
+ e.setCoords(env2D_2);
+ double tol_cluster = InternalUtils
+ .adjust_tolerance_for_TE_clustering(tolerance);
+ e.inflate(tol_cluster, tol_cluster);
+
+ if (!env2D_1.isIntersecting(e))// also includes the empty geometry
+ // cases
{
if (geometry_a.getDimension() <= geometry_b.getDimension()) {
Geometry geom = normalizeResult_(
@@ -1708,11 +1858,6 @@ static Geometry[] intersectionEx(Geometry geometry_a, Geometry geometry_b,
}
}
- Envelope2D envMerged = new Envelope2D();
- envMerged.setCoords(env2D_1);
- envMerged.merge(env2D_2);
- double tolerance = InternalUtils.calculateToleranceFromGeometry(sr,
- envMerged, true);// conservative to have same effect as simplify
TopologicalOperations topoOps = new TopologicalOperations();
EditShape edit_shape = new EditShape();
@@ -1829,53 +1974,6 @@ private void flushVertices_(int geometry, AttributeStreamOfInt32 vertices) {
shape.setClosedPath(path, true);// need to close polygon rings
}
- private void removeSpikes_(int cuttee, int cutter) {
- int idCuttee = m_topo_graph.getGeometryID(cuttee);
- int idCutter = m_topo_graph.getGeometryID(cutter);
- int visitedIndex = m_topo_graph.createUserIndexForHalfEdges();
- for (int cluster = m_topo_graph.getFirstCluster(); cluster != -1; cluster = m_topo_graph
- .getNextCluster(cluster)) {
- int firstHalfEdge = m_topo_graph.getClusterHalfEdge(cluster);
- if (firstHalfEdge == -1)
- continue;
-
- int half_edge = firstHalfEdge;
-
- do {
- int visited = m_topo_graph.getHalfEdgeUserIndex(half_edge,
- visitedIndex);
- if (visited != 1) {
- int halfEdgeParentage = m_topo_graph
- .getHalfEdgeParentage(half_edge);
- int halfEdgeFaceParentage = m_topo_graph
- .getHalfEdgeFaceParentage(half_edge);
- if (halfEdgeParentage != (idCuttee | idCutter)
- && halfEdgeFaceParentage != 0) {
- int faceHalfEdge = half_edge;
- do {
- int faceHalfEdgeNext = m_topo_graph
- .getHalfEdgeNext(faceHalfEdge);
- if (m_topo_graph.getHalfEdgePrev(faceHalfEdge) == m_topo_graph
- .getHalfEdgeTwin(faceHalfEdge))
- m_topo_graph.deleteEdgeInternal_(faceHalfEdge);
- else
- m_topo_graph.setHalfEdgeUserIndex(faceHalfEdge,
- visitedIndex, 1);
-
- faceHalfEdge = faceHalfEdgeNext;
- } while (faceHalfEdge != half_edge);
- } else {
- m_topo_graph.setHalfEdgeUserIndex(half_edge,
- visitedIndex, 1);
- }
- }
-
- half_edge = m_topo_graph.getHalfEdgeNext(m_topo_graph
- .getHalfEdgeTwin(half_edge));
- } while (half_edge != firstHalfEdge);
- }
- }
-
private void setHalfEdgeOrientations_(int orientationIndex, int cutter) {
EditShape shape = m_topo_graph.getShape();
@@ -2031,7 +2129,7 @@ private void processPolygonCuts_(int orientationIndex, int sideIndex,
private void cutPolygonPolyline_(int sideIndex, int cuttee, int cutter,
AttributeStreamOfInt32 cutHandles) {
- removeSpikes_(cuttee, cutter);
+ m_topo_graph.removeSpikes_();
int orientationIndex = -1;
if (sideIndex != -1) {
@@ -2056,5 +2154,14 @@ private void cutPolygonPolyline_(int sideIndex, int cuttee, int cutter,
CompareCuts compareCuts = new CompareCuts(shape);
cutHandles.Sort(0, cutCount, compareCuts);
}
+
+ //call this if EditShape instance has to survive the TopologicalOperations life.
+ void removeShape() {
+ if (m_topo_graph != null) {
+ m_topo_graph.removeShape();
+ m_topo_graph = null;
+ }
+
+ }
}
diff --git a/src/com/esri/core/geometry/Transformation2D.java b/src/main/java/com/esri/core/geometry/Transformation2D.java
similarity index 98%
rename from src/com/esri/core/geometry/Transformation2D.java
rename to src/main/java/com/esri/core/geometry/Transformation2D.java
index 1d90b17c..1704628a 100644
--- a/src/com/esri/core/geometry/Transformation2D.java
+++ b/src/main/java/com/esri/core/geometry/Transformation2D.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,9 +24,13 @@
package com.esri.core.geometry;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_TRANSFORMATION_2D;
+
/**
- * The affine transformation class for 2D.
- * Vector is a row:
+ * The affine transformation class for 2D.
+ *
+ * Vector is a row:
+ *
*
|m11 m12 0|
*
| x y 1| * |m21 m22 0| = |m11 * x + m21 * y + m31 m12 * x + m22 * y + m32 1|
*
|m31 m32 1|
@@ -467,9 +471,9 @@ public boolean isIdentity(double tol) {
if (pt.sqrLength() > tol * tol)
return false;
- pt.setCoords(1., 0.);
+ pt.setCoords(1.0, 0.0);
transform(pt, pt);
- pt.sub(Point2D.construct(1., 0));
+ pt.sub(Point2D.construct(1.0, 0.0));
return pt.sqrLength() <= tol * tol;
}
@@ -510,12 +514,12 @@ public boolean isShift() {
* The tolerance value.
*/
public boolean isShift(double tol) {
- Point2D pt = transformWithoutShift(Point2D.construct(0., 1.));
+ Point2D pt = transformWithoutShift(Point2D.construct(0.0, 1.0));
pt.y -= 1.0;
if (pt.sqrLength() > tol * tol)
return false;
- pt = transformWithoutShift(Point2D.construct(1., 0.));
+ pt = transformWithoutShift(Point2D.construct(1.0, 0.0));
pt.x -= 1.0;
return pt.sqrLength() <= tol * tol;
}
@@ -919,4 +923,8 @@ public void extractScaleTransform(Transformation2D scale,
rotateNshearNshift.multiply(this);
}
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_TRANSFORMATION_2D;
+ }
}
diff --git a/src/com/esri/core/geometry/Transformation3D.java b/src/main/java/com/esri/core/geometry/Transformation3D.java
similarity index 84%
rename from src/com/esri/core/geometry/Transformation3D.java
rename to src/main/java/com/esri/core/geometry/Transformation3D.java
index 5f914381..cac98407 100644
--- a/src/com/esri/core/geometry/Transformation3D.java
+++ b/src/main/java/com/esri/core/geometry/Transformation3D.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,20 +25,15 @@
package com.esri.core.geometry;
/**
- * @brief The 3D affine transformation Vector is a row: |m11 m12 0| | x y 1| *
- * |m21 m22 0| = |m11 * x + m21 * y + m31 m12 * x + m22 * y + m32 1| |m31
- * m32 1| Then elements of the Transformation2D are as follows: |xx yx 0|
- * | x y 1| * |xy yy 0| = |xx * x + xy * y + xd yx * x + yy * y + yd 1|
- * |xd yd 1|
+ * The 3D affine transformation class.
*
- * We use matrices for transformations of the vectors as rows (case 2).
- * That means the math expressions on the Geometry matrix operations
- * should be writen like this: v' = v * M1 * M2 * M3 = ( (v * M1) * M2 )
- * * M3, where v is a vector, Mn are the matrices. This is equivalent to
- * the following line of code: ResultVector =
- * (M1.Mul(M2).Mul(M3)).Transform(Vector)
+ * We use matrices for transformations of the vectors as rows. That means the
+ * math expressions on the Geometry matrix operations should be writen like
+ * this: v' = v * M1 * M2 * M3 = ( (v * M1) * M2 ) * M3, where v is a vector, Mn
+ * are the matrices. This is equivalent to the following line of code:
+ * ResultVector = (M1.Mul(M2).Mul(M3)).Transform(Vector)
*/
-final class Transformation3D {
+final public class Transformation3D {
public double xx, yx, zx, xd, xy, yy, zy, yd, xz, yz, zz, zd;
@@ -117,7 +112,7 @@ public Envelope3D transform(Envelope3D env) {
return env;
}
- void transform(Point3D[] pointsIn, int count, Point3D[] pointsOut) {
+ public void transform(Point3D[] pointsIn, int count, Point3D[] pointsOut) {
for (int i = 0; i < count; i++) {
Point3D res = new Point3D();
Point3D src = pointsIn[i];
@@ -201,13 +196,11 @@ public static void multiply(Transformation3D a, Transformation3D b,
*
* @param src
* The input transformation.
- * @param dst
- * The inverse of the input transformation.
- * @throws Throws
- * the GeometryException("math_singularity") exception if the
- * Inverse can not be calculated.
+ * @param result
+ * The inverse of the input transformation. Throws the
+ * GeometryException("math singularity") exception if the Inverse
+ * can not be calculated.
*/
- // static
public static void inverse(Transformation3D src, Transformation3D result) {
double det = src.xx * (src.yy * src.zz - src.zy * src.yz) - src.yx
* (src.xy * src.zz - src.zy * src.xz) + src.zx
diff --git a/src/com/esri/core/geometry/Treap.java b/src/main/java/com/esri/core/geometry/Treap.java
similarity index 98%
rename from src/com/esri/core/geometry/Treap.java
rename to src/main/java/com/esri/core/geometry/Treap.java
index e97840a6..89cd6383 100644
--- a/src/com/esri/core/geometry/Treap.java
+++ b/src/main/java/com/esri/core/geometry/Treap.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -199,19 +199,21 @@ public int addBiggestElement(int element, int treap) {
// get_duplicate_element reutrns the node of the already existing element.
public int addElementAtPosition(int prevNode, int nextNode, int element,
boolean bUnique, boolean bCallCompare, int treap) {
- int treap_;
- if (treap == -1) {
+ int treap_ = treap;
+ if (treap_ == -1) {
if (m_defaultTreap == nullNode())
m_defaultTreap = createTreap(-1);
treap_ = m_defaultTreap;
- } else {
- treap_ = treap;
}
// dbg_check_(m_root);
- if (getRoot_(treap_) == nullNode()
- || (prevNode == nullNode() && nextNode == nullNode()))
- throw new GeometryException("invald call");
+ if (getRoot_(treap_) == nullNode()) {
+ assert (nextNode == nullNode() && prevNode == nullNode());
+ int root = newNode_(element);
+ setRoot_(root, treap_);
+ addToList_(-1, root, treap_);
+ return root;
+ }
int cmpNext;
int cmpPrev;
diff --git a/src/com/esri/core/geometry/UserCancelException.java b/src/main/java/com/esri/core/geometry/UserCancelException.java
similarity index 97%
rename from src/com/esri/core/geometry/UserCancelException.java
rename to src/main/java/com/esri/core/geometry/UserCancelException.java
index bf0b1f2b..d72479a1 100644
--- a/src/com/esri/core/geometry/UserCancelException.java
+++ b/src/main/java/com/esri/core/geometry/UserCancelException.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/VertexDescription.java b/src/main/java/com/esri/core/geometry/VertexDescription.java
similarity index 72%
rename from src/com/esri/core/geometry/VertexDescription.java
rename to src/main/java/com/esri/core/geometry/VertexDescription.java
index b10afe2e..07e7630b 100644
--- a/src/com/esri/core/geometry/VertexDescription.java
+++ b/src/main/java/com/esri/core/geometry/VertexDescription.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@
package com.esri.core.geometry;
+import java.util.Arrays;
+
/**
* Describes the vertex format of a Geometry.
*
@@ -40,69 +42,39 @@
* table. You may look the vertices of a Geometry as if they are stored in a
* database table, and the VertexDescription defines the fields of the table.
*/
-public class VertexDescription {
-
- private double[] m_defaultPointAttributes;
- private int[] m_pointAttributeOffsets;
- int m_attributeCount;
- int m_total_component_count;
-
- int[] m_semantics;
-
- int[] m_semanticsToIndexMap;
-
- int m_hash;
+public final class VertexDescription {
+ /**
+ * Describes the attribute and, in case of predefined attributes, provides a
+ * hint of the attribute use.
+ */
+ public interface Semantics {
+ static final int POSITION = 0; // xy coordinates of a point (2D
+ // vector of double, linear
+ // interpolation)
- static double[] _defaultValues = { 0, 0, NumberUtils.NaN(), 0, 0, 0, 0, 0,
- 0 };
+ static final int Z = 1; // z coordinates of a point (double,
+ // linear interpolation)
- static int[] _interpolation = { Interpolation.LINEAR, Interpolation.LINEAR,
- Interpolation.LINEAR, Interpolation.NONE, Interpolation.ANGULAR,
- Interpolation.LINEAR, Interpolation.LINEAR, Interpolation.LINEAR,
- Interpolation.NONE, // FIXME this last value doesnt exist in native
- };
+ static final int M = 2; // m attribute (double, linear
+ // interpolation)
- static int[] _persistence = { Persistence.enumDouble,
- Persistence.enumDouble, Persistence.enumDouble,
- Persistence.enumInt32, Persistence.enumFloat,
- Persistence.enumFloat, Persistence.enumFloat,
- Persistence.enumFloat, Persistence.enumInt32, // FIXME, this last
- // Int32 doesn't
- // exist in native
- };
+ static final int ID = 3; // id (int, no interpolation)
- static int[] _persistencesize = { 4, 8, 4, 8, 1, 2 };
+ static final int NORMAL = 4; // xyz coordinates of normal vector
+ // (float, angular interpolation)
- static int[] _components = { 2, 1, 1, 1, 3, 1, 2, 3, 2, };
+ static final int TEXTURE1D = 5; // u coordinates of texture
+ // (float, linear interpolation)
- VertexDescription() {
- m_attributeCount = 0;
- m_total_component_count = 0;
+ static final int TEXTURE2D = 6; // uv coordinates of texture
+ // (float, linear interpolation)
- }
+ static final int TEXTURE3D = 7; // uvw coordinates of texture
+ // (float, linear interpolation)
- VertexDescription(int hashValue, VertexDescription other) {
- m_attributeCount = other.m_attributeCount;
- m_total_component_count = other.m_total_component_count;
- m_semantics = other.m_semantics.clone();
- m_semanticsToIndexMap = other.m_semanticsToIndexMap.clone();
- m_hash = other.m_hash;
+ static final int ID2 = 8; // two component ID
- // Prepare default values for the Point geometry.
- m_pointAttributeOffsets = new int[getAttributeCount()];
- int offset = 0;
- for (int i = 0; i < getAttributeCount(); i++) {
- m_pointAttributeOffsets[i] = offset;
- offset += getComponentCount(m_semantics[i]);
- }
- m_total_component_count = offset;
- m_defaultPointAttributes = new double[offset];
- for (int i = 0; i < getAttributeCount(); i++) {
- int components = getComponentCount(getSemantics(i));
- double dv = getDefaultValue(getSemantics(i));
- for (int icomp = 0; icomp < components; icomp++)
- m_defaultPointAttributes[m_pointAttributeOffsets[i] + icomp] = dv;
- }
+ static final int MAXSEMANTICS = 8; // the max semantics value
}
/**
@@ -136,40 +108,6 @@ interface Persistence {
public static final int enumInt16 = 5;
};
- /**
- * Describes the attribute and, in case of predefined attributes, provides a
- * hint of the attribute use.
- */
- public interface Semantics {
- static final int POSITION = 0; // xy coordinates of a point (2D
- // vector of double, linear
- // interpolation)
-
- static final int Z = 1; // z coordinates of a point (double,
- // linear interpolation)
-
- static final int M = 2; // m attribute (double, linear
- // interpolation)
-
- static final int ID = 3; // id (int, no interpolation)
-
- static final int NORMAL = 4; // xyz coordinates of normal vector
- // (float, angular interpolation)
-
- static final int TEXTURE1D = 5; // u coordinates of texture
- // (float, linear interpolation)
-
- static final int TEXTURE2D = 6; // uv coordinates of texture
- // (float, linear interpolation)
-
- static final int TEXTURE3D = 7; // uvw coordinates of texture
- // (float, linear interpolation)
-
- static final int ID2 = 8; // two component ID
-
- static final int MAXSEMANTICS = 10; // the max semantics value
- }
-
/**
* Returns the attribute count of this description. The value is always
* greater or equal to 1. The first attribute is always a POSITION.
@@ -183,13 +121,10 @@ public final int getAttributeCount() {
*
* @param attributeIndex
* The index of the attribute in the description. Max value is
- * GetAttributeCount() - 1.
+ * getAttributeCount() - 1.
*/
public final int getSemantics(int attributeIndex) {
- if (attributeIndex < 0 || attributeIndex > m_attributeCount)
- throw new IllegalArgumentException();
-
- return m_semantics[attributeIndex];
+ return m_indexToSemantics[attributeIndex];
}
/**
@@ -251,20 +186,6 @@ public static int getComponentCount(int semantics) {
return _components[semantics];
}
- /**
- * Returns True for integer persistence type.
- */
- static boolean isIntegerPersistence(int persistence) {
- return persistence < Persistence.enumInt32;
- }
-
- /**
- * Returns True for integer semantics type.
- */
- static boolean isIntegerSemantics(int semantics) {
- return isIntegerPersistence(getPersistence(semantics));
- }
-
/**
* Returns True if the attribute with the given name and given set exists.
*
@@ -272,27 +193,40 @@ static boolean isIntegerSemantics(int semantics) {
* The semantics of the attribute.
*/
public boolean hasAttribute(int semantics) {
- return m_semanticsToIndexMap[semantics] >= 0;
+ return (m_semanticsBitArray & (1 << semantics)) != 0;
+ }
+
+ /**
+ * Returns True if this vertex description includes all attributes from the
+ * src.
+ *
+ * @param src
+ * The Vertex_description to compare with.
+ * @return The function returns false, only when this description does not
+ * have some of the attribute that src has.
+ */
+ public final boolean hasAttributesFrom(VertexDescription src) {
+ return (m_semanticsBitArray & src.m_semanticsBitArray) == src.m_semanticsBitArray;
}
/**
* Returns True, if the vertex has Z attribute.
*/
- public boolean hasZ() {
+ public final boolean hasZ() {
return hasAttribute(Semantics.Z);
}
/**
* Returns True, if the vertex has M attribute.
*/
- public boolean hasM() {
+ public final boolean hasM() {
return hasAttribute(Semantics.M);
}
/**
* Returns True, if the vertex has ID attribute.
*/
- public boolean hasID() {
+ public final boolean hasID() {
return hasAttribute(Semantics.ID);
}
@@ -304,15 +238,15 @@ public static double getDefaultValue(int semantics) {
return _defaultValues[semantics];
}
- int getPointAttributeOffset_(int attribute_index) {
- return m_pointAttributeOffsets[attribute_index];
+ int getPointAttributeOffset_(int attributeIndex) {
+ return m_pointAttributeOffsets[attributeIndex];
}
/**
* Returns the total component count.
*/
public int getTotalComponentCount() {
- return m_total_component_count;
+ return m_totalComponentCount;
}
/**
@@ -325,28 +259,19 @@ public static boolean isDefaultValue(int semantics, double v) {
.doubleToInt64Bits(v);
}
- static int getPersistenceFromInt(int size) {
- if (size == 4)
- return Persistence.enumInt32;
- else if (size == 8)
- return Persistence.enumInt64;
- else
- throw new IllegalArgumentException();
+ static boolean isIntegerPersistence(int persistence) {
+ return persistence >= Persistence.enumInt32;
}
+ static boolean isIntegerSemantics(int semantics) {
+ return isIntegerPersistence(getPersistence(semantics));
+ }
+
@Override
public boolean equals(Object _other) {
return (Object) this == _other;
}
- int calculateHashImpl() {
- int v = NumberUtils.hash(m_semantics[0]);
- for (int i = 1; i < m_attributeCount; i++)
- v = NumberUtils.hash(v, m_semantics[i]);
-
- return v; // if attribute size is 1, it returns 0
- }
-
/**
*
* Returns a packed array of double representation of all ordinates of
@@ -375,19 +300,81 @@ int _getPointAttributeOffsetFromSemantics(int semantics) {
return m_pointAttributeOffsets[getAttributeIndex(semantics)];
}
- int _getTotalComponents() {
- return m_defaultPointAttributes.length;
- }
-
@Override
public int hashCode() {
return m_hash;
}
int _getSemanticsImpl(int attributeIndex) {
- return m_semantics[attributeIndex];
+ return m_indexToSemantics[attributeIndex];
+ }
+
+ VertexDescription(int bitMask) {
+ m_semanticsBitArray = bitMask;
+ m_attributeCount = 0;
+ m_totalComponentCount = 0;
+ m_semanticsToIndexMap = new int[Semantics.MAXSEMANTICS + 1];
+ Arrays.fill(m_semanticsToIndexMap, -1);
+ for (int i = 0, flag = 1, n = Semantics.MAXSEMANTICS + 1; i < n; i++) {
+ if ((bitMask & flag) != 0) {
+ m_semanticsToIndexMap[i] = m_attributeCount;
+ m_attributeCount++;
+ int comps = getComponentCount(i);
+ m_totalComponentCount += comps;
+ }
+
+ flag <<= 1;
+ }
+
+ m_indexToSemantics = new int[m_attributeCount];
+ for (int i = 0, n = Semantics.MAXSEMANTICS + 1; i < n; i++) {
+ int attrib = m_semanticsToIndexMap[i];
+ if (attrib >= 0)
+ m_indexToSemantics[attrib] = i;
+ }
+
+ m_defaultPointAttributes = new double[m_totalComponentCount];
+ m_pointAttributeOffsets = new int[m_attributeCount];
+ int offset = 0;
+ for (int i = 0, n = m_attributeCount; i < n; i++) {
+ int semantics = getSemantics(i);
+ int comps = getComponentCount(semantics);
+ double v = getDefaultValue(semantics);
+ m_pointAttributeOffsets[i] = offset;
+ for (int icomp = 0; icomp < comps; icomp++) {
+ m_defaultPointAttributes[offset] = v;
+ offset++;
+ }
+ }
+
+ m_hash = NumberUtils.hash(m_semanticsBitArray);
}
- // TODO: clone, equald, hashcode - whats really needed?
+ private int m_attributeCount;
+ int m_semanticsBitArray; //the main component
+ private int m_totalComponentCount;
+ private int m_hash;
+
+ private int[] m_semanticsToIndexMap;
+ private int[] m_indexToSemantics;
+ private int[] m_pointAttributeOffsets;
+ private double[] m_defaultPointAttributes;
+
+ static final double[] _defaultValues = { 0, 0, NumberUtils.NaN(), 0, 0, 0,
+ 0, 0, 0 };
+
+ static final int[] _interpolation = { Interpolation.LINEAR,
+ Interpolation.LINEAR, Interpolation.LINEAR, Interpolation.NONE,
+ Interpolation.ANGULAR, Interpolation.LINEAR, Interpolation.LINEAR,
+ Interpolation.LINEAR, Interpolation.NONE, };
+
+ static final int[] _persistence = { Persistence.enumDouble,
+ Persistence.enumDouble, Persistence.enumDouble,
+ Persistence.enumInt32, Persistence.enumFloat,
+ Persistence.enumFloat, Persistence.enumFloat,
+ Persistence.enumFloat, Persistence.enumInt32, };
+
+ static final int[] _persistencesize = { 4, 8, 4, 8, 1, 2 };
+ static final int[] _components = { 2, 1, 1, 1, 3, 1, 2, 3, 2, };
}
diff --git a/src/main/java/com/esri/core/geometry/VertexDescriptionDesignerImpl.java b/src/main/java/com/esri/core/geometry/VertexDescriptionDesignerImpl.java
new file mode 100644
index 00000000..c6d69b15
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/VertexDescriptionDesignerImpl.java
@@ -0,0 +1,90 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.util.Arrays;
+
+import com.esri.core.geometry.VertexDescription.Semantics;
+
+/**
+ * This factory class allows to describe and create a VertexDescription
+ * instance.
+ */
+final class VertexDescriptionDesignerImpl {
+ static VertexDescription getVertexDescription(int descriptionBitMask) {
+ return VertexDescriptionHash.getInstance()
+ .FindOrAdd(descriptionBitMask);
+ }
+
+ static VertexDescription getMergedVertexDescription(
+ VertexDescription descr1, VertexDescription descr2) {
+ int mask = descr1.m_semanticsBitArray | descr2.m_semanticsBitArray;
+ if ((mask & descr1.m_semanticsBitArray) == mask) {
+ return descr1;
+ } else if ((mask & descr2.m_semanticsBitArray) == mask) {
+ return descr2;
+ }
+
+ return getVertexDescription(mask);
+ }
+
+ static VertexDescription getMergedVertexDescription(
+ VertexDescription descr, int semantics) {
+ int mask = descr.m_semanticsBitArray | (1 << semantics);
+ if ((mask & descr.m_semanticsBitArray) == mask) {
+ return descr;
+ }
+
+ return getVertexDescription(mask);
+ }
+
+ static VertexDescription removeSemanticsFromVertexDescription(
+ VertexDescription descr, int semanticsToRemove) {
+ int mask = (descr.m_semanticsBitArray | (1 << (int) semanticsToRemove))
+ - (1 << (int) semanticsToRemove);
+ if (mask == descr.m_semanticsBitArray) {
+ return descr;
+ }
+
+ return getVertexDescription(mask);
+ }
+
+ static VertexDescription getDefaultDescriptor2D() {
+ return VertexDescriptionHash.getInstance().getVD2D();
+ }
+
+ static VertexDescription getDefaultDescriptor3D() {
+ return VertexDescriptionHash.getInstance().getVD3D();
+ }
+
+ static int[] mapAttributes(VertexDescription src, VertexDescription dest) {
+ int[] srcToDst = new int[src.getAttributeCount()];
+ Arrays.fill(srcToDst, -1);
+ for (int i = 0, nsrc = src.getAttributeCount(); i < nsrc; i++) {
+ srcToDst[i] = dest.getAttributeIndex(src.getSemantics(i));
+ }
+ return srcToDst;
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/VertexDescriptionHash.java b/src/main/java/com/esri/core/geometry/VertexDescriptionHash.java
new file mode 100644
index 00000000..8e12dfec
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/VertexDescriptionHash.java
@@ -0,0 +1,81 @@
+/*
+ Copyright 1995-2015 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.VertexDescription.Semantics;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A hash object singleton that stores all VertexDescription instances via
+ * WeakReference. The purpose of the class is to keep track of created
+ * VertexDescription instances to prevent duplicates.
+ */
+final class VertexDescriptionHash {
+ HashMap m_map = new HashMap();
+
+ private static VertexDescription m_vd2D = new VertexDescription(1);
+ private static VertexDescription m_vd3D = new VertexDescription(3);
+
+ private static final VertexDescriptionHash INSTANCE = new VertexDescriptionHash();
+
+ private VertexDescriptionHash() {
+ m_map.put(1, m_vd2D);
+ m_map.put(3, m_vd3D);
+ }
+
+ public static VertexDescriptionHash getInstance() {
+ return INSTANCE;
+ }
+
+ public final VertexDescription getVD2D() {
+ return m_vd2D;
+ }
+
+ public final VertexDescription getVD3D() {
+ return m_vd3D;
+ }
+
+ public final VertexDescription FindOrAdd(int bitSet) {
+ if (bitSet == 1)
+ return m_vd2D;
+ if (bitSet == 3)
+ return m_vd3D;
+
+ synchronized (this) {
+ VertexDescription vd = m_map.get(bitSet);
+ if (vd == null) {
+ vd = new VertexDescription(bitSet);
+ m_map.put(bitSet, vd);
+ }
+
+ return vd;
+ }
+ }
+
+}
diff --git a/src/com/esri/core/geometry/WkbByteOrder.java b/src/main/java/com/esri/core/geometry/WkbByteOrder.java
similarity index 97%
rename from src/com/esri/core/geometry/WkbByteOrder.java
rename to src/main/java/com/esri/core/geometry/WkbByteOrder.java
index 9f474f20..c973d82e 100644
--- a/src/com/esri/core/geometry/WkbByteOrder.java
+++ b/src/main/java/com/esri/core/geometry/WkbByteOrder.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/WkbExportFlags.java b/src/main/java/com/esri/core/geometry/WkbExportFlags.java
similarity index 98%
rename from src/com/esri/core/geometry/WkbExportFlags.java
rename to src/main/java/com/esri/core/geometry/WkbExportFlags.java
index d4637df8..115f39c7 100644
--- a/src/com/esri/core/geometry/WkbExportFlags.java
+++ b/src/main/java/com/esri/core/geometry/WkbExportFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/WkbGeometryType.java b/src/main/java/com/esri/core/geometry/WkbGeometryType.java
similarity index 98%
rename from src/com/esri/core/geometry/WkbGeometryType.java
rename to src/main/java/com/esri/core/geometry/WkbGeometryType.java
index 07d142d0..20932cf9 100644
--- a/src/com/esri/core/geometry/WkbGeometryType.java
+++ b/src/main/java/com/esri/core/geometry/WkbGeometryType.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/WkbImportFlags.java b/src/main/java/com/esri/core/geometry/WkbImportFlags.java
similarity index 97%
rename from src/com/esri/core/geometry/WkbImportFlags.java
rename to src/main/java/com/esri/core/geometry/WkbImportFlags.java
index 5f1f0392..fdadc8a5 100644
--- a/src/com/esri/core/geometry/WkbImportFlags.java
+++ b/src/main/java/com/esri/core/geometry/WkbImportFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/Wkid.java b/src/main/java/com/esri/core/geometry/Wkid.java
similarity index 98%
rename from src/com/esri/core/geometry/Wkid.java
rename to src/main/java/com/esri/core/geometry/Wkid.java
index 9ecf2bd7..9fd9cca0 100644
--- a/src/com/esri/core/geometry/Wkid.java
+++ b/src/main/java/com/esri/core/geometry/Wkid.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -146,7 +146,7 @@ public static double find_tolerance_from_wkid(int wkid) {
if (tol == 1e38) {
int old = wkid_to_old(wkid);
if (old != wkid)
- tol = find_tolerance_from_wkid_helper(wkid);
+ tol = find_tolerance_from_wkid_helper(old);
if (tol == 1e38)
return 1e-10;
}
diff --git a/src/com/esri/core/geometry/Wkt.java b/src/main/java/com/esri/core/geometry/Wkt.java
similarity index 99%
rename from src/com/esri/core/geometry/Wkt.java
rename to src/main/java/com/esri/core/geometry/Wkt.java
index 08db42f1..a4c2a7f4 100644
--- a/src/com/esri/core/geometry/Wkt.java
+++ b/src/main/java/com/esri/core/geometry/Wkt.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/WktExportFlags.java b/src/main/java/com/esri/core/geometry/WktExportFlags.java
similarity index 98%
rename from src/com/esri/core/geometry/WktExportFlags.java
rename to src/main/java/com/esri/core/geometry/WktExportFlags.java
index 2756135d..c9974be5 100644
--- a/src/com/esri/core/geometry/WktExportFlags.java
+++ b/src/main/java/com/esri/core/geometry/WktExportFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/WktImportFlags.java b/src/main/java/com/esri/core/geometry/WktImportFlags.java
similarity index 97%
rename from src/com/esri/core/geometry/WktImportFlags.java
rename to src/main/java/com/esri/core/geometry/WktImportFlags.java
index 9bc57d6a..d16c2d20 100644
--- a/src/com/esri/core/geometry/WktImportFlags.java
+++ b/src/main/java/com/esri/core/geometry/WktImportFlags.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/com/esri/core/geometry/WktParser.java b/src/main/java/com/esri/core/geometry/WktParser.java
similarity index 97%
rename from src/com/esri/core/geometry/WktParser.java
rename to src/main/java/com/esri/core/geometry/WktParser.java
index 91f0198d..7f79ed5f 100644
--- a/src/com/esri/core/geometry/WktParser.java
+++ b/src/main/java/com/esri/core/geometry/WktParser.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2015 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -222,7 +222,7 @@ private void geometry_() {
m_function_stack.removeLast();
if (m_start_token + 5 <= m_wkt_string.length()
- && m_wkt_string.regionMatches(true, m_start_token, "points", 0,
+ && m_wkt_string.regionMatches(true, m_start_token, "point", 0,
5)) {
m_end_token = m_start_token + 5;
m_current_token_type = WktToken.point;
@@ -264,7 +264,12 @@ private void geometry_() {
m_current_token_type = WktToken.geometrycollection;
m_function_stack.add(State.geometryCollectionStart);
} else {
- throw new IllegalArgumentException();
+ //String snippet = (m_wkt_string.length() > 200 ? m_wkt_string
+ // .substring(0, 200) + "..." : m_wkt_string);
+ //throw new IllegalArgumentException(
+ // "Could not parse Well-Known Text: " + snippet);
+ throw new IllegalArgumentException(
+ "Could not parse Well-Known Text around position: " + m_end_token);
}
m_function_stack.add(State.attributes);
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCConcreteGeometryCollection.java b/src/main/java/com/esri/core/geometry/ogc/OGCConcreteGeometryCollection.java
new file mode 100644
index 00000000..66eb1310
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCConcreteGeometryCollection.java
@@ -0,0 +1,958 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry.ogc;
+
+import com.esri.core.geometry.Envelope;
+import com.esri.core.geometry.GeoJsonExportFlags;
+import com.esri.core.geometry.Geometry;
+import com.esri.core.geometry.GeometryCursor;
+import com.esri.core.geometry.GeometryException;
+import com.esri.core.geometry.MultiPath;
+import com.esri.core.geometry.MultiPoint;
+import com.esri.core.geometry.MultiVertexGeometry;
+import com.esri.core.geometry.NumberUtils;
+import com.esri.core.geometry.OGCStructureInternal;
+import com.esri.core.geometry.OperatorConvexHull;
+import com.esri.core.geometry.OperatorDifference;
+import com.esri.core.geometry.OperatorExportToGeoJson;
+import com.esri.core.geometry.OperatorIntersection;
+import com.esri.core.geometry.OperatorUnion;
+import com.esri.core.geometry.Point;
+import com.esri.core.geometry.Polygon;
+import com.esri.core.geometry.Polyline;
+import com.esri.core.geometry.SimpleGeometryCursor;
+import com.esri.core.geometry.SpatialReference;
+import com.esri.core.geometry.VertexDescription;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_OGC_CONCRETE_GEOMETRY_COLLECTION;
+
+public class OGCConcreteGeometryCollection extends OGCGeometryCollection {
+ static public String TYPE = "GeometryCollection";
+
+ List geometries;
+
+ public OGCConcreteGeometryCollection(List geoms,
+ SpatialReference sr) {
+ geometries = geoms;
+ esriSR = sr;
+ }
+
+ public OGCConcreteGeometryCollection(GeometryCursor geoms,
+ SpatialReference sr) {
+ List ogcGeoms = new ArrayList(10);
+ for (Geometry g = geoms.next(); g != null; g = geoms.next()) {
+ ogcGeoms.add(createFromEsriGeometry(g, sr));
+ }
+
+ geometries = ogcGeoms;
+ esriSR = sr;
+ }
+
+ public OGCConcreteGeometryCollection(OGCGeometry geom, SpatialReference sr) {
+ geometries = new ArrayList(1);
+ geometries.add(geom);
+ esriSR = sr;
+ }
+
+ public OGCConcreteGeometryCollection(SpatialReference sr) {
+ geometries = new ArrayList();
+ esriSR = sr;
+ }
+
+ @Override
+ public int dimension() {
+ int maxD = 0;
+ for (int i = 0, n = numGeometries(); i < n; i++)
+ maxD = Math.max(geometryN(i).dimension(), maxD);
+
+ return maxD;
+ }
+
+ @Override
+ public int coordinateDimension() {
+ return isEmpty() ? 2 : geometryN(0).coordinateDimension();
+ }
+
+ @Override
+ public boolean is3D() {
+ return !isEmpty() && geometries.get(0).is3D();
+ }
+
+ @Override
+ public boolean isMeasured() {
+ return !isEmpty() && geometries.get(0).isMeasured();
+ }
+
+ @Override
+ public OGCGeometry envelope() {
+ GeometryCursor gc = getEsriGeometryCursor();
+ Envelope env = new Envelope();
+ for (Geometry g = gc.next(); g != null; g = gc.next()) {
+ Envelope e = new Envelope();
+ g.queryEnvelope(e);
+ env.merge(e);
+ }
+
+ Polygon polygon = new Polygon();
+ polygon.addEnvelope(env, false);
+ return new OGCPolygon(polygon, esriSR);
+ }
+
+ @Override
+ public int numGeometries() {
+ return geometries.size();
+ }
+
+ @Override
+ public OGCGeometry geometryN(int n) {
+ return geometries.get(n);
+ }
+
+ @Override
+ public String geometryType() {
+ return TYPE;
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ long size = SIZE_OF_OGC_CONCRETE_GEOMETRY_COLLECTION;
+ if (geometries != null) {
+ for (OGCGeometry geometry : geometries) {
+ size += geometry.estimateMemorySize();
+ }
+ }
+ return size;
+ }
+
+ @Override
+ public String asText() {
+ StringBuilder sb = new StringBuilder("GEOMETRYCOLLECTION ");
+ if (is3D()) {
+ sb.append('Z');
+ }
+ if (isMeasured()) {
+ sb.append('M');
+ }
+ if (is3D() || isMeasured())
+ sb.append(' ');
+
+ int n = numGeometries();
+
+ if (n == 0) {
+ sb.append("EMPTY");
+ return sb.toString();
+ }
+
+ sb.append('(');
+ for (int i = 0; i < n; i++) {
+ if (i > 0)
+ sb.append(", ");
+
+ sb.append(geometryN(i).asText());
+ }
+ sb.append(')');
+
+ return sb.toString();
+ }
+
+ @Override
+ public ByteBuffer asBinary() {
+
+ ArrayList buffers = new ArrayList(0);
+
+ int size = 9;
+ int n = numGeometries();
+ for (int i = 0; i < n; i++) {
+ ByteBuffer buffer = geometryN(i).asBinary();
+ buffers.add(buffer);
+ size += buffer.capacity();
+ }
+
+ ByteBuffer wkbBuffer = ByteBuffer.allocate(size).order(
+ ByteOrder.nativeOrder());
+
+ byte byteOrder = (byte) (wkbBuffer.order() == ByteOrder.LITTLE_ENDIAN ? 1
+ : 0);
+ int wkbType = 7;
+
+ if (is3D())
+ wkbType += 1000;
+ if (isMeasured())
+ wkbType += 2000;
+
+ wkbBuffer.put(0, byteOrder);
+ wkbBuffer.putInt(1, wkbType);
+ wkbBuffer.putInt(5, n);
+
+ int offset = 9;
+ for (int i = 0; i < n; i++) {
+ byte[] arr = buffers.get(i).array();
+ System.arraycopy(arr, 0, wkbBuffer.array(), offset, arr.length);
+ offset += arr.length;
+ }
+
+ return wkbBuffer;
+ }
+
+ @Override
+ public String asGeoJson() {
+ return asGeoJsonImpl(GeoJsonExportFlags.geoJsonExportDefaults);
+ }
+
+ @Override
+ String asGeoJsonImpl(int export_flags) {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("{\"type\":\"GeometryCollection\",\"geometries\":");
+
+ sb.append("[");
+ for (int i = 0, n = numGeometries(); i < n; i++) {
+ if (i > 0)
+ sb.append(",");
+
+ if (geometryN(i) != null)
+ sb.append(geometryN(i).asGeoJsonImpl(GeoJsonExportFlags.geoJsonExportSkipCRS));
+ }
+
+ sb.append("],\"crs\":");
+
+ if (esriSR != null) {
+ String crs_value = OperatorExportToGeoJson.local().exportSpatialReference(0, esriSR);
+ sb.append(crs_value);
+ } else {
+ sb.append("\"null\"");
+ }
+
+ sb.append("}");
+
+ return sb.toString();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return numGeometries() == 0;
+ }
+
+ @Override
+ public double MinZ() {
+ double z = Double.NaN;
+ for (int i = 0, n = numGeometries(); i < n; i++)
+ z = i == 0 ? geometryN(i).MinZ() : Math.min(geometryN(i).MinZ(), z);
+ return z;
+ }
+
+ @Override
+ public double MaxZ() {
+ double z = Double.NaN;
+ for (int i = 0, n = numGeometries(); i < n; i++)
+ z = i == 0 ? geometryN(i).MaxZ() : Math.min(geometryN(i).MaxZ(), z);
+ return z;
+ }
+
+ @Override
+ public double MinMeasure() {
+ double z = Double.NaN;
+ for (int i = 0, n = numGeometries(); i < n; i++)
+ z = i == 0 ? geometryN(i).MinMeasure() : Math.min(geometryN(i)
+ .MinMeasure(), z);
+ return z;
+ }
+
+ @Override
+ public double MaxMeasure() {
+ double z = Double.NaN;
+ for (int i = 0, n = numGeometries(); i < n; i++)
+ z = i == 0 ? geometryN(i).MaxMeasure() : Math.min(geometryN(i)
+ .MaxMeasure(), z);
+ return z;
+ }
+
+ @Override
+ public boolean isSimple() {
+ for (int i = 0, n = numGeometries(); i < n; i++)
+ if (!geometryN(i).isSimple())
+ return false;
+
+ return true;
+ }
+
+ /**
+ * makeSimpleRelaxed is not supported for the GeometryCollection instance.
+ *
+ */
+ @Override
+ public OGCGeometry makeSimple() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isSimpleRelaxed() {
+ for (int i = 0, n = numGeometries(); i < n; i++)
+ if (!geometryN(i).isSimpleRelaxed())
+ return false;
+ return true;
+ }
+
+ /**
+ * makeSimpleRelaxed is not supported for the GeometryCollection instance.
+ *
+ */
+ @Override
+ public OGCGeometry makeSimpleRelaxed(boolean forceProcessing) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public OGCGeometry boundary() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public OGCGeometry locateAlong(double mValue) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public OGCGeometry locateBetween(double mStart, double mEnd) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Geometry getEsriGeometry() {
+ return null;
+ }
+
+ @Override
+ public GeometryCursor getEsriGeometryCursor() {
+ return new GeometryCursorOGC(geometries);
+ }
+
+ @Override
+ protected boolean isConcreteGeometryCollection() {
+ return true;
+ }
+
+ private static class GeometryCursorOGC extends GeometryCursor {
+ private int m_index;
+ private int m_ind;
+ private List m_geoms;
+ GeometryCursor m_curs;
+
+ GeometryCursorOGC(List geoms) {
+ m_geoms = geoms;
+ m_index = -1;
+ m_curs = null;
+ m_ind = 0;
+ }
+
+ @Override
+ public Geometry next() {
+ while (true) {
+ if (m_curs != null) {
+ Geometry g = m_curs.next();
+ if (g != null) {
+ m_index++;
+ return g;
+ }
+ m_curs = null;
+ }
+ if (m_ind >= m_geoms.size())
+ return null;
+
+ int i = m_ind;
+ m_ind++;
+ if (m_geoms.get(i) == null)
+ continue;// filter out nulls
+ if (!m_geoms.get(i).isConcreteGeometryCollection()) {
+ m_index++;
+ return m_geoms.get(i).getEsriGeometry();
+ } else {
+ OGCConcreteGeometryCollection gc = (OGCConcreteGeometryCollection) m_geoms
+ .get(i);
+ m_curs = new GeometryCursorOGC(gc.geometries);
+ return next();
+ }
+ }
+ }
+
+ @Override
+ public int getGeometryID() {
+ return m_index;
+ }
+
+ }
+
+ @Override
+ public OGCGeometry convexHull() {
+ GeometryCursor cursor = OperatorConvexHull.local().execute(
+ getEsriGeometryCursor(), false, null);
+ MultiPoint mp = new MultiPoint();
+ Polygon polygon = new Polygon();
+ VertexDescription vd = null;
+ for (Geometry geom = cursor.next(); geom != null; geom = cursor.next()) {
+ vd = geom.getDescription();
+ if (geom.isEmpty())
+ continue;
+
+ if (geom.getType() == Geometry.Type.Polygon) {
+ polygon.add((MultiPath) geom, false);
+ }
+ else if (geom.getType() == Geometry.Type.Polyline) {
+ mp.add((MultiVertexGeometry) geom, 0, -1);
+ }
+ else if (geom.getType() == Geometry.Type.Point) {
+ mp.add((Point) geom);
+ }
+ else {
+ throw new GeometryException("internal error");
+ }
+ }
+
+ Geometry resultGeom = null;
+ if (!mp.isEmpty()) {
+ resultGeom = OperatorConvexHull.local().execute(mp, null);
+ }
+
+ if (!polygon.isEmpty()) {
+ if (resultGeom != null && !resultGeom.isEmpty()) {
+ Geometry[] geoms = { resultGeom, polygon };
+ resultGeom = OperatorConvexHull.local().execute(
+ new SimpleGeometryCursor(geoms), true, null).next();
+ }
+ else {
+ resultGeom = OperatorConvexHull.local().execute(polygon, null);
+ }
+ }
+
+ if (resultGeom == null) {
+ Point pt = new Point();
+ if (vd != null)
+ pt.assignVertexDescription(vd);
+
+ return new OGCPoint(pt, getEsriSpatialReference());
+ }
+
+ return OGCGeometry.createFromEsriGeometry(resultGeom, getEsriSpatialReference(), false);
+ }
+
+ @Override
+ public void setSpatialReference(SpatialReference esriSR_) {
+ esriSR = esriSR_;
+ for (int i = 0, n = geometries.size(); i < n; i++) {
+ if (geometries.get(i) != null)
+ geometries.get(i).setSpatialReference(esriSR_);
+ }
+ }
+
+ @Override
+ public OGCGeometry convertToMulti() {
+ return this;
+ }
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ int n = numGeometries();
+ if (n == 0) {
+ return this;
+ }
+
+ if (n == 1) {
+ return geometryN(0).reduceFromMulti();
+ }
+
+ return this;
+ }
+
+ @Override
+ public String asJson() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null)
+ return false;
+
+ if (other == this)
+ return true;
+
+ if (other.getClass() != getClass())
+ return false;
+
+ OGCConcreteGeometryCollection another = (OGCConcreteGeometryCollection)other;
+ if (geometries != null) {
+ if (!geometries.equals(another.geometries))
+ return false;
+ }
+ else if (another.geometries != null)
+ return false;
+
+ if (esriSR == another.esriSR) {
+ return true;
+ }
+
+ if (esriSR != null && another.esriSR != null) {
+ return esriSR.equals(another.esriSR);
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ if (geometries != null)
+ hash = geometries.hashCode();
+
+ if (esriSR != null)
+ hash = NumberUtils.hashCombine(hash, esriSR.hashCode());
+
+ return hash;
+ }
+
+ @Override
+ public double distance(OGCGeometry another) {
+ if (this == another)
+ return isEmpty() ? Double.NaN : 0;
+
+ double minD = Double.NaN;
+ for (int i = 0, n = numGeometries(); i < n; ++i) {
+ // TODO Skip expensive distance computation if bounding boxes are further away than minD
+ double d = geometryN(i).distance(another);
+ if (d < minD || Double.isNaN(minD)) {
+ minD = d;
+ // TODO Replace zero with tolerance defined by the spatial reference
+ if (minD == 0) {
+ break;
+ }
+ }
+ }
+
+ return minD;
+ }
+
+ //
+ //Relational operations
+ @Override
+ public boolean overlaps(OGCGeometry another) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean touches(OGCGeometry another) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean crosses(OGCGeometry another) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean relate(OGCGeometry another, String matrix) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean disjoint(OGCGeometry another) {
+ if (isEmpty() || another.isEmpty())
+ return true;
+
+ if (this == another)
+ return false;
+
+ //TODO: a simple envelope test
+
+ OGCConcreteGeometryCollection flattened1 = flatten();
+ if (flattened1.isEmpty())
+ return true;
+ OGCConcreteGeometryCollection otherCol = new OGCConcreteGeometryCollection(another, esriSR);
+ OGCConcreteGeometryCollection flattened2 = otherCol.flatten();
+ if (flattened2.isEmpty())
+ return true;
+
+ for (int i = 0, n1 = flattened1.numGeometries(); i < n1; ++i) {
+ OGCGeometry g1 = flattened1.geometryN(i);
+ for (int j = 0, n2 = flattened2.numGeometries(); j < n2; ++j) {
+ OGCGeometry g2 = flattened2.geometryN(j);
+ if (!g1.disjoint(g2))
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean contains(OGCGeometry another) {
+ if (isEmpty() || another.isEmpty())
+ return false;
+
+ if (this == another)
+ return true;
+
+ return another.difference(this).isEmpty();
+ }
+
+ @Override
+ public boolean Equals(OGCGeometry another) {
+ if (this == another)
+ return !isEmpty();
+
+ if (another == null)
+ return false;
+
+
+ OGCGeometry g1 = reduceFromMulti();
+ String t1 = g1.geometryType();
+ OGCGeometry g2 = reduceFromMulti();
+ if (t1 != g2.geometryType()) {
+ return false;
+ }
+
+ if (t1 != OGCConcreteGeometryCollection.TYPE) {
+ return g1.Equals(g2);
+ }
+
+ OGCConcreteGeometryCollection gc1 = (OGCConcreteGeometryCollection)g1;
+ OGCConcreteGeometryCollection gc2 = (OGCConcreteGeometryCollection)g2;
+ // TODO Assuming input geometries are simple and valid, remove-overlaps would be a no-op.
+ // Hence, calling flatten() should be sufficient.
+ gc1 = gc1.flattenAndRemoveOverlaps();
+ gc2 = gc2.flattenAndRemoveOverlaps();
+ int n = gc1.numGeometries();
+ if (n != gc2.numGeometries()) {
+ return false;
+ }
+
+ for (int i = 0; i < n; ++i) {
+ if (!gc1.geometryN(i).Equals(gc2.geometryN(i))) {
+ return false;
+ }
+ }
+
+ return n > 0;
+ }
+
+ private static OGCConcreteGeometryCollection toGeometryCollection(OGCGeometry geometry)
+ {
+ if (geometry.geometryType() != OGCConcreteGeometryCollection.TYPE) {
+ return new OGCConcreteGeometryCollection(geometry, geometry.getEsriSpatialReference());
+ }
+
+ return (OGCConcreteGeometryCollection) geometry;
+ }
+
+ private static List toList(GeometryCursor cursor)
+ {
+ List geometries = new ArrayList();
+ for (Geometry geometry = cursor.next(); geometry != null; geometry = cursor.next()) {
+ geometries.add(geometry);
+ }
+ return geometries;
+ }
+
+ //Topological
+ @Override
+ public OGCGeometry difference(OGCGeometry another) {
+ if (isEmpty() || another.isEmpty()) {
+ return this;
+ }
+
+ List geometries = toList(prepare_for_ops_(toGeometryCollection(this)));
+ List otherGeometries = toList(prepare_for_ops_(toGeometryCollection(another)));
+
+ List result = new ArrayList();
+ for (Geometry geometry : geometries) {
+ for (Geometry otherGeometry : otherGeometries) {
+ if (geometry.getDimension() > otherGeometry.getDimension()) {
+ continue; //subtracting lower dimension has no effect.
+ }
+
+ geometry = OperatorDifference.local().execute(geometry, otherGeometry, esriSR, null);
+ if (geometry.isEmpty()) {
+ break;
+ }
+ }
+
+ if (!geometry.isEmpty()) {
+ result.add(OGCGeometry.createFromEsriGeometry(geometry, esriSR));
+ }
+ }
+
+ if (result.size() == 1) {
+ return result.get(0).reduceFromMulti();
+ }
+
+ return new OGCConcreteGeometryCollection(result, esriSR).flattenAndRemoveOverlaps();
+ }
+
+ @Override
+ public OGCGeometry intersection(OGCGeometry another) {
+ if (isEmpty() || another.isEmpty()) {
+ return new OGCConcreteGeometryCollection(esriSR);
+ }
+
+ List geometries = toList(prepare_for_ops_(toGeometryCollection(this)));
+ List otherGeometries = toList(prepare_for_ops_(toGeometryCollection(another)));
+
+ List result = new ArrayList();
+ for (Geometry geometry : geometries) {
+ for (Geometry otherGeometry : otherGeometries) {
+ GeometryCursor intersectionCursor = OperatorIntersection.local().execute(new SimpleGeometryCursor(geometry), new SimpleGeometryCursor(otherGeometry), esriSR, null, 7);
+ OGCGeometry intersection = OGCGeometry.createFromEsriCursor(intersectionCursor, esriSR, true);
+ if (!intersection.isEmpty()) {
+ result.add(intersection);
+ }
+ }
+ }
+
+ if (result.size() == 1) {
+ return result.get(0).reduceFromMulti();
+ }
+
+ return new OGCConcreteGeometryCollection(result, esriSR).flattenAndRemoveOverlaps();
+ }
+
+ @Override
+ public OGCGeometry symDifference(OGCGeometry another) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Checks if collection is flattened.
+ * @return True for the flattened collection. A flattened collection contains up to three non-empty geometries:
+ * an OGCMultiPoint, an OGCMultiPolygon, and an OGCMultiLineString.
+ */
+ public boolean isFlattened() {
+ int n = numGeometries();
+ if (n > 3)
+ return false;
+
+ int dimension = -1;
+ for (int i = 0; i < n; ++i) {
+ OGCGeometry g = geometryN(i);
+ if (g.isEmpty())
+ return false;//no empty allowed
+
+ String t = g.geometryType();
+ if (t != OGCMultiPoint.TYPE && t != OGCMultiPolygon.TYPE && t != OGCMultiLineString.TYPE)
+ return false;
+
+ //check strict order of geometry dimensions
+ int d = g.dimension();
+ if (d <= dimension)
+ return false;
+
+ dimension = d;
+ }
+
+ return true;
+ }
+
+ /**
+ * Flattens Geometry Collection.
+ * The result collection contains up to three geometries:
+ * an OGCMultiPoint, an OGCMultilineString, and an OGCMultiPolygon (in that order).
+ * @return A flattened Geometry Collection, or self if already flattened.
+ */
+ public OGCConcreteGeometryCollection flatten() {
+ if (isFlattened()) {
+ return this;
+ }
+
+ OGCMultiPoint multiPoint = null;
+ ArrayList polygons = null;
+ OGCMultiLineString polyline = null;
+ GeometryCursor gc = getEsriGeometryCursor();
+ for (Geometry g = gc.next(); g != null; g = gc.next()) {
+ if (g.isEmpty())
+ continue;
+
+ Geometry.Type t = g.getType();
+
+ if (t == Geometry.Type.Point) {
+ if (multiPoint == null) {
+ multiPoint = new OGCMultiPoint(esriSR);
+ }
+
+ ((MultiPoint)multiPoint.getEsriGeometry()).add((Point)g);
+ continue;
+ }
+
+ if (t == Geometry.Type.MultiPoint) {
+ if (multiPoint == null)
+ multiPoint = new OGCMultiPoint(esriSR);
+
+ ((MultiPoint)multiPoint.getEsriGeometry()).add((MultiPoint)g, 0, -1);
+ continue;
+ }
+
+ if (t == Geometry.Type.Polyline) {
+ if (polyline == null)
+ polyline = new OGCMultiLineString(esriSR);
+
+ ((MultiPath)polyline.getEsriGeometry()).add((Polyline)g, false);
+ continue;
+ }
+
+ if (t == Geometry.Type.Polygon) {
+ if (polygons == null)
+ polygons = new ArrayList();
+
+ polygons.add(g);
+ continue;
+ }
+
+ throw new GeometryException("internal error");//what else?
+ }
+
+ List list = new ArrayList();
+
+ if (multiPoint != null)
+ list.add(multiPoint);
+
+ if (polyline != null)
+ list.add(polyline);
+
+ if (polygons != null) {
+ GeometryCursor unionedPolygons = OperatorUnion.local().execute(new SimpleGeometryCursor(polygons), esriSR, null);
+ Geometry g = unionedPolygons.next();
+ if (!g.isEmpty()) {
+ list.add(new OGCMultiPolygon((Polygon)g, esriSR));
+ }
+
+ }
+
+ return new OGCConcreteGeometryCollection(list, esriSR);
+ }
+
+ /**
+ * Fixes topological overlaps in the GeometryCollecion.
+ * This is equivalent to union of the geometry collection elements.
+ *
+ * TODO "flattened" collection is supposed to contain only mutli-geometries, but this method may return single geometries
+ * e.g. for GEOMETRYCOLLECTION (LINESTRING (...)) it returns GEOMETRYCOLLECTION (LINESTRING (...))
+ * and not GEOMETRYCOLLECTION (MULTILINESTRING (...))
+ * @return A geometry collection that is flattened and has no overlapping elements.
+ */
+ public OGCConcreteGeometryCollection flattenAndRemoveOverlaps() {
+
+ //flatten and crack/cluster
+ GeometryCursor cursor = OGCStructureInternal.prepare_for_ops_(flatten().getEsriGeometryCursor(), esriSR);
+
+ //make sure geometries don't overlap
+ return new OGCConcreteGeometryCollection(removeOverlapsHelper_(toList(cursor)), esriSR);
+ }
+
+ private GeometryCursor removeOverlapsHelper_(List geoms) {
+ List result = new ArrayList();
+ for (int i = 0; i < geoms.size(); ++i) {
+ Geometry current = geoms.get(i);
+ if (current.isEmpty())
+ continue;
+
+ for (int j = i + 1; j < geoms.size(); ++j) {
+ Geometry subG = geoms.get(j);
+ current = OperatorDifference.local().execute(current, subG, esriSR, null);
+ if (current.isEmpty())
+ break;
+ }
+
+ if (current.isEmpty())
+ continue;
+
+ result.add(current);
+ }
+
+ return new SimpleGeometryCursor(result);
+ }
+
+ private static class FlatteningCollectionCursor extends GeometryCursor {
+ private List m_collections;
+ private GeometryCursor m_current;
+ private int m_index;
+ FlatteningCollectionCursor(List collections) {
+ m_collections = collections;
+ m_index = -1;
+ m_current = null;
+ }
+
+ @Override
+ public Geometry next() {
+ while (m_collections != null) {
+ if (m_current != null) {
+ Geometry g = m_current.next();
+ if (g == null) {
+ m_current = null;
+ continue;
+ }
+
+ return g;
+ }
+ else {
+ m_index++;
+ if (m_index < m_collections.size()) {
+ m_current = m_collections.get(m_index).flatten().getEsriGeometryCursor();
+ continue;
+ }
+ else {
+ m_collections = null;
+ m_index = -1;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public int getGeometryID() {
+ return m_index;
+ }
+
+ };
+
+ //Collectively processes group of geometry collections (intersects all segments and clusters points).
+ //Flattens collections, removes overlaps.
+ //Once done, the result collections would work well for topological and relational operations.
+ private GeometryCursor prepare_for_ops_(OGCConcreteGeometryCollection collection) {
+ assert(collection != null && !collection.isEmpty());
+ GeometryCursor prepared = OGCStructureInternal.prepare_for_ops_(collection.flatten().getEsriGeometryCursor(), esriSR);
+ return removeOverlapsHelper_(toList(prepared));
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCCurve.java b/src/main/java/com/esri/core/geometry/ogc/OGCCurve.java
new file mode 100644
index 00000000..dd229e5e
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCCurve.java
@@ -0,0 +1,53 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry.ogc;
+
+import com.esri.core.geometry.MultiPoint;
+
+public abstract class OGCCurve extends OGCGeometry {
+ public abstract double length();
+
+ public abstract OGCPoint startPoint();
+
+ public abstract OGCPoint endPoint();
+
+ public abstract boolean isClosed();
+
+ public boolean isRing() {
+ return isSimple() && isClosed();
+ }
+
+ @Override
+ public OGCGeometry boundary() {
+ if (isEmpty())
+ return new OGCMultiPoint(this.getEsriSpatialReference());
+
+ if (isClosed())
+ return new OGCMultiPoint(new MultiPoint(getEsriGeometry()
+ .getDescription()), esriSR);// return empty multipoint;
+ else
+ return new OGCMultiPoint(startPoint(), endPoint());
+ }
+}
diff --git a/src/com/esri/core/geometry/ogc/OGCGeometry.java b/src/main/java/com/esri/core/geometry/ogc/OGCGeometry.java
similarity index 70%
rename from src/com/esri/core/geometry/ogc/OGCGeometry.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCGeometry.java
index 47c5c304..a6fdeaa9 100644
--- a/src/com/esri/core/geometry/ogc/OGCGeometry.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCGeometry.java
@@ -1,14 +1,28 @@
-package com.esri.core.geometry.ogc;
+/*
+ Copyright 1995-2018 Esri
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
+ Licensed 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
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.json.JSONException;
+ 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry.ogc;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Envelope1D;
@@ -16,19 +30,21 @@
import com.esri.core.geometry.GeometryCursor;
import com.esri.core.geometry.GeometryCursorAppend;
import com.esri.core.geometry.GeometryEngine;
+import com.esri.core.geometry.JsonParserReader;
import com.esri.core.geometry.MapGeometry;
import com.esri.core.geometry.MapOGCStructure;
import com.esri.core.geometry.MultiPoint;
+import com.esri.core.geometry.NumberUtils;
import com.esri.core.geometry.OGCStructure;
import com.esri.core.geometry.Operator;
import com.esri.core.geometry.OperatorBuffer;
+import com.esri.core.geometry.OperatorCentroid2D;
import com.esri.core.geometry.OperatorConvexHull;
-import com.esri.core.geometry.OperatorExportToWkb;
import com.esri.core.geometry.OperatorExportToGeoJson;
+import com.esri.core.geometry.OperatorExportToWkb;
import com.esri.core.geometry.OperatorFactoryLocal;
import com.esri.core.geometry.OperatorImportFromESRIShape;
import com.esri.core.geometry.OperatorImportFromGeoJson;
-import com.esri.core.geometry.OperatorImportFromJson;
import com.esri.core.geometry.OperatorImportFromWkb;
import com.esri.core.geometry.OperatorImportFromWkt;
import com.esri.core.geometry.OperatorIntersection;
@@ -36,12 +52,17 @@
import com.esri.core.geometry.OperatorSimplifyOGC;
import com.esri.core.geometry.OperatorUnion;
import com.esri.core.geometry.Point;
+import com.esri.core.geometry.Point2D;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.geometry.SimpleGeometryCursor;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.VertexDescription;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+
/**
* OGC Simple Feature Access specification v.1.2.1
*
@@ -65,6 +86,17 @@ public int coordinateDimension() {
abstract public String geometryType();
+ /**
+ * Returns an estimate of this object size in bytes.
+ *
+ * This estimate doesn't include the size of the {@link SpatialReference} object
+ * because instances of {@link SpatialReference} are expected to be shared among
+ * geometry objects.
+ *
+ * @return Returns an estimate of this object size in bytes.
+ */
+ public abstract long estimateMemorySize();
+
public int SRID() {
if (esriSR == null)
return 0;
@@ -90,12 +122,26 @@ public ByteBuffer asBinary() {
return op.execute(0, getEsriGeometry(), null);
}
- public String asGeoJson() {
- OperatorExportToGeoJson op = (OperatorExportToGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToGeoJson);
- return op.execute(getEsriGeometry());
- }
+ public String asGeoJson() {
+ OperatorExportToGeoJson op = (OperatorExportToGeoJson) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.ExportToGeoJson);
+ return op.execute(esriSR, getEsriGeometry());
+ }
+
+ String asGeoJsonImpl(int export_flags) {
+ OperatorExportToGeoJson op = (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToGeoJson);
+ return op.execute(export_flags, esriSR, getEsriGeometry());
+ }
+
+ /**
+ *
+ * @return Convert to REST JSON.
+ */
+ public String asJson() {
+ return GeometryEngine.geometryToJson(esriSR, getEsriGeometry());
+ }
+
public boolean isEmpty() {
return getEsriGeometry().isEmpty();
}
@@ -131,10 +177,12 @@ public double MaxMeasure() {
* "simple" for each geometry type.
*
* The method has O(n log n) complexity when the input geometry is simple.
- * For non-simple geometries, it terminates immediately when the first issue is
- * encountered.
+ * For non-simple geometries, it terminates immediately when the first issue
+ * is encountered.
*
* @return True if geometry is simple and false otherwise.
+ *
+ * Note: If isSimple is true, then isSimpleRelaxed is true too.
*/
public boolean isSimple() {
return OperatorSimplifyOGC.local().isSimpleOGC(getEsriGeometry(),
@@ -145,26 +193,47 @@ public boolean isSimple() {
* Extension method - checks if geometry is simple for Geodatabase.
*
* @return Returns true if geometry is simple, false otherwise.
+ *
+ * Note: If isSimpleRelaxed is true, then isSimple is either true or false. Geodatabase has more relaxed requirements for simple geometries than OGC.
*/
public boolean isSimpleRelaxed() {
OperatorSimplify op = (OperatorSimplify) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Simplify);
- return op
- .isSimpleAsFeature(getEsriGeometry(), esriSR, true, null, null);
+ return op.isSimpleAsFeature(getEsriGeometry(), esriSR, true, null, null);
}
+ @Deprecated
+ /**
+ * Use makeSimpleRelaxed instead.
+ */
+ public OGCGeometry MakeSimpleRelaxed(boolean forceProcessing) {
+ return makeSimpleRelaxed(forceProcessing);
+ }
/**
* Makes a simple geometry for Geodatabase.
*
* @return Returns simplified geometry.
+ *
+ * Note: isSimpleRelaxed should return true after this operation.
*/
- public OGCGeometry MakeSimpleRelaxed(boolean forceProcessing) {
+ public OGCGeometry makeSimpleRelaxed(boolean forceProcessing) {
OperatorSimplify op = (OperatorSimplify) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Simplify);
return OGCGeometry.createFromEsriGeometry(
op.execute(getEsriGeometry(), esriSR, forceProcessing, null),
esriSR);
}
+
+ /**
+ * Resolves topological issues in this geometry and makes it Simple according to OGC specification.
+ *
+ * @return Returns simplified geometry.
+ *
+ * Note: isSimple and isSimpleRelaxed should return true after this operation.
+ */
+ public OGCGeometry makeSimple() {
+ return simplifyBunch_(getEsriGeometryCursor());
+ }
public boolean is3D() {
return getEsriGeometry().getDescription().hasAttribute(
@@ -178,15 +247,37 @@ public boolean isMeasured() {
abstract public OGCGeometry boundary();
- // query
- public boolean equals(OGCGeometry another) {
+ /**
+ * OGC equals. Performs topological comparison with tolerance.
+ * This is different from equals(Object), that uses exact comparison.
+ */
+ public boolean Equals(OGCGeometry another) {
+ if (this == another)
+ return !isEmpty();
+
+ if (another == null)
+ return false;
+
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ return another.Equals(this);
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.equals(geom1, geom2,
getEsriSpatialReference());
}
+ @Deprecated
+ public boolean equals(OGCGeometry another) {
+ return Equals(another);
+ }
+
public boolean disjoint(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ return another.disjoint(this);
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.disjoint(geom1, geom2,
@@ -198,6 +289,11 @@ public boolean intersects(OGCGeometry another) {
}
public boolean touches(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.touches(geom1, geom2,
@@ -205,6 +301,11 @@ public boolean touches(OGCGeometry another) {
}
public boolean crosses(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.crosses(geom1, geom2,
@@ -212,13 +313,14 @@ public boolean crosses(OGCGeometry another) {
}
public boolean within(OGCGeometry another) {
- com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
- com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
- return com.esri.core.geometry.GeometryEngine.within(geom1, geom2,
- getEsriSpatialReference());
+ return another.contains(this);
}
public boolean contains(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ return new OGCConcreteGeometryCollection(this, esriSR).contains(another);
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.contains(geom1, geom2,
@@ -226,6 +328,11 @@ public boolean contains(OGCGeometry another) {
}
public boolean overlaps(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ // TODO
+ throw new UnsupportedOperationException();
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.overlaps(geom1, geom2,
@@ -233,6 +340,11 @@ public boolean overlaps(OGCGeometry another) {
}
public boolean relate(OGCGeometry another, String matrix) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.relate(geom1, geom2,
@@ -245,6 +357,14 @@ public boolean relate(OGCGeometry another, String matrix) {
// analysis
public double distance(OGCGeometry another) {
+ if (this == another) {
+ return isEmpty() ? Double.NaN : 0;
+ }
+
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ return another.distance(this);
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return com.esri.core.geometry.GeometryEngine.distance(geom1, geom2,
@@ -258,14 +378,6 @@ public double distance(OGCGeometry another) {
// As a result there are at most three geometries, each geometry is Simple.
// Afterwards
// it produces a single OGCGeometry.
- //
- // Note: Not complete yet. We'll use this method to implement the OGC
- // Simplify (or MakeValid method)
- // At this moment, method removes self intersections, and clusters vertices,
- // but may sometimes
- // produce geometries with self-tangency or polygons with disconnected
- // interior
- // which are simple for ArcObjects, but non-simple for OGC.
private OGCGeometry simplifyBunch_(GeometryCursor gc) {
// Combines geometries into multipoint, polyline, and polygon types,
// simplifying them and unioning them,
@@ -354,15 +466,43 @@ public OGCGeometry buffer(double distance) {
return OGCGeometry.createFromEsriGeometry(cursor.next(), esriSR);
}
- public OGCGeometry convexHull() {
- com.esri.core.geometry.OperatorConvexHull op = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
+ public OGCGeometry buffer(double distance, int max_vertices_in_full_circle, double max_deviation) {
+ OperatorBuffer op = (OperatorBuffer) OperatorFactoryLocal.getInstance()
+ .getOperator(Operator.Type.Buffer);
+ if (distance == 0) {// when distance is 0, return self (maybe we should
+ // create a copy instead).
+ return this;
+ }
+
+ double d[] = { distance };
com.esri.core.geometry.GeometryCursor cursor = op.execute(
- getEsriGeometryCursor(), true, null);
+ getEsriGeometryCursor(), getEsriSpatialReference(), d, max_deviation, max_vertices_in_full_circle, true,
+ null);
+ return OGCGeometry.createFromEsriGeometry(cursor.next(), esriSR);
+ }
+
+ public OGCGeometry centroid() {
+ OperatorCentroid2D op = (OperatorCentroid2D) OperatorFactoryLocal.getInstance()
+ .getOperator(Operator.Type.Centroid2D);
+
+ Point2D centroid = op.execute(getEsriGeometry(), null);
+ if (centroid == null) {
+ return OGCGeometry.createFromEsriGeometry(new Point(), esriSR);
+ }
+ return OGCGeometry.createFromEsriGeometry(new Point(centroid), esriSR);
+ }
+
+ public OGCGeometry convexHull() {
+ com.esri.core.geometry.GeometryCursor cursor = OperatorConvexHull.local().execute(
+ getEsriGeometryCursor(), false, null);
return OGCGeometry.createFromEsriCursor(cursor, esriSR);
}
public OGCGeometry intersection(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ return (new OGCConcreteGeometryCollection(this, esriSR)).intersection(another);
+ }
+
com.esri.core.geometry.OperatorIntersection op = (OperatorIntersection) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Intersection);
com.esri.core.geometry.GeometryCursor cursor = op.execute(
@@ -372,6 +512,18 @@ public OGCGeometry intersection(OGCGeometry another) {
}
public OGCGeometry union(OGCGeometry another) {
+ String thisType = geometryType();
+ String anotherType = another.geometryType();
+ if (thisType != anotherType || thisType == OGCConcreteGeometryCollection.TYPE) {
+ //heterogeneous union.
+ //We make a geometry collection, then process to union parts and remove overlaps.
+ ArrayList geoms = new ArrayList();
+ geoms.add(this);
+ geoms.add(another);
+ OGCConcreteGeometryCollection geomCol = new OGCConcreteGeometryCollection(geoms, esriSR);
+ return geomCol.flattenAndRemoveOverlaps().reduceFromMulti();
+ }
+
OperatorUnion op = (OperatorUnion) OperatorFactoryLocal.getInstance()
.getOperator(Operator.Type.Union);
GeometryCursorAppend ap = new GeometryCursorAppend(
@@ -382,6 +534,10 @@ public OGCGeometry union(OGCGeometry another) {
}
public OGCGeometry difference(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ return (new OGCConcreteGeometryCollection(this, esriSR)).difference(another);
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return createFromEsriGeometry(
@@ -390,6 +546,11 @@ public OGCGeometry difference(OGCGeometry another) {
}
public OGCGeometry symDifference(OGCGeometry another) {
+ if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) {
+ // TODO
+ throw new UnsupportedOperationException();
+ }
+
com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
return createFromEsriGeometry(
@@ -461,17 +622,13 @@ public static OGCGeometry fromEsriShape(ByteBuffer buffer) {
SpatialReference.create(4326));
}
- public static OGCGeometry fromJson(String string)
- throws JsonParseException, IOException {
- JsonFactory factory = new JsonFactory();
- JsonParser jsonParserPt = factory.createJsonParser(string);
- jsonParserPt.nextToken();
- MapGeometry mapGeom = GeometryEngine.jsonToGeometry(jsonParserPt);
+ public static OGCGeometry fromJson(String string) {
+ MapGeometry mapGeom = GeometryEngine.jsonToGeometry(JsonParserReader.createFromString(string));
return OGCGeometry.createFromEsriGeometry(mapGeom.getGeometry(),
mapGeom.getSpatialReference());
}
- public static OGCGeometry fromGeoJson(String string) throws JSONException {
+ public static OGCGeometry fromGeoJson(String string) {
OperatorImportFromGeoJson op = (OperatorImportFromGeoJson) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
MapOGCStructure mapOGCStructure = op.executeOGC(0, string, null);
@@ -634,4 +791,80 @@ protected boolean isConcreteGeometryCollection() {
public void setSpatialReference(SpatialReference esriSR_) {
esriSR = esriSR_;
}
+
+ /**
+ * Converts this Geometry to the OGCMulti* if it is not OGCMulti* or
+ * OGCGeometryCollection already.
+ *
+ * @return OGCMulti* or OGCGeometryCollection instance.
+ */
+ public abstract OGCGeometry convertToMulti();
+
+ /**
+ * For the geometry collection types, when it has 1 or 0 elements, converts a MultiPolygon to Polygon,
+ * MultiPoint to Point, MultiLineString to a LineString, and
+ * OGCConcretGeometryCollection to the reduced element it contains.
+ *
+ * If OGCConcretGeometryCollection is empty, returns self.
+ *
+ * @return A reduced geometry or this.
+ */
+ public abstract OGCGeometry reduceFromMulti();
+
+ @Override
+ public String toString() {
+ String snippet = asText();
+ if (snippet.length() > 200) {
+ snippet = snippet.substring(0, 197) + "...";
+ }
+ return String
+ .format("%s: %s", this.getClass().getSimpleName(), snippet);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null)
+ return false;
+
+ if (other == this)
+ return true;
+
+ if (other.getClass() != getClass())
+ return false;
+
+ OGCGeometry another = (OGCGeometry)other;
+ com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
+ com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry();
+
+ if (geom1 == null) {
+ if (geom2 != null)
+ return false;
+ }
+ else if (!geom1.equals(geom2)) {
+ return false;
+ }
+
+ if (esriSR == another.esriSR) {
+ return true;
+ }
+
+ if (esriSR != null && another.esriSR != null) {
+ return esriSR.equals(another.esriSR);
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ com.esri.core.geometry.Geometry geom1 = getEsriGeometry();
+ if (geom1 != null)
+ hash = geom1.hashCode();
+
+ if (esriSR != null)
+ hash = NumberUtils.hashCombine(hash, esriSR.hashCode());
+
+ return hash;
+ }
}
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCGeometryCollection.java b/src/main/java/com/esri/core/geometry/ogc/OGCGeometryCollection.java
new file mode 100644
index 00000000..ef5a3631
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCGeometryCollection.java
@@ -0,0 +1,38 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry.ogc;
+
+public abstract class OGCGeometryCollection extends OGCGeometry {
+ /**
+ * Returns the number of geometries in this GeometryCollection.
+ */
+ public abstract int numGeometries();
+
+ /**
+ * Returns the Nth geometry in this GeometryCollection.
+ * @param n The 0 based index of the geometry.
+ */
+ public abstract OGCGeometry geometryN(int n);
+}
diff --git a/src/com/esri/core/geometry/ogc/OGCLineString.java b/src/main/java/com/esri/core/geometry/ogc/OGCLineString.java
similarity index 67%
rename from src/com/esri/core/geometry/ogc/OGCLineString.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCLineString.java
index 6310a77f..f044128d 100644
--- a/src/com/esri/core/geometry/ogc/OGCLineString.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCLineString.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry.ogc;
import com.esri.core.geometry.Geometry;
@@ -10,9 +34,14 @@
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.WkbExportFlags;
import com.esri.core.geometry.WktExportFlags;
+
import java.nio.ByteBuffer;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_OGC_LINE_STRING;
+
public class OGCLineString extends OGCCurve {
+ static public String TYPE = "LineString";
+
/**
* The number of Points in this LineString.
*/
@@ -54,6 +83,9 @@ public OGCPoint pointN(int n) {
@Override
public boolean isClosed() {
+ if (isEmpty())
+ return false;
+
return multiPath.isClosedPathInXYPlane(0);
}
@@ -89,7 +121,13 @@ public OGCPoint endPoint() {
@Override
public String geometryType() {
- return "LineString";
+ return TYPE;
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_OGC_LINE_STRING + (multiPath != null ? multiPath.estimateMemorySize() : 0);
}
@Override
@@ -107,5 +145,16 @@ public Geometry getEsriGeometry() {
return multiPath;
}
+ @Override
+ public OGCGeometry convertToMulti()
+ {
+ return new OGCMultiLineString((Polyline)multiPath, esriSR);
+ }
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ return this;
+ }
+
MultiPath multiPath;
}
diff --git a/src/com/esri/core/geometry/ogc/OGCLinearRing.java b/src/main/java/com/esri/core/geometry/ogc/OGCLinearRing.java
similarity index 53%
rename from src/com/esri/core/geometry/ogc/OGCLinearRing.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCLinearRing.java
index e733f6a5..a4b67d78 100644
--- a/src/com/esri/core/geometry/ogc/OGCLinearRing.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCLinearRing.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry.ogc;
import com.esri.core.geometry.MultiPath;
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCMultiCurve.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiCurve.java
new file mode 100644
index 00000000..9aae3bee
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCMultiCurve.java
@@ -0,0 +1,48 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry.ogc;
+
+import com.esri.core.geometry.MultiPath;
+
+public abstract class OGCMultiCurve extends OGCGeometryCollection {
+ public int numGeometries() {
+ MultiPath mp = (MultiPath) getEsriGeometry();
+ return mp.getPathCount();
+ }
+
+ public boolean isClosed() {
+ MultiPath mp = (MultiPath) getEsriGeometry();
+ for (int i = 0, n = mp.getPathCount(); i < n; i++) {
+ if (!mp.isClosedPathInXYPlane(i))
+ return false;
+ }
+
+ return true;
+ }
+
+ public double length() {
+ return getEsriGeometry().calculateLength2D();
+ }
+}
diff --git a/src/com/esri/core/geometry/ogc/OGCMultiLineString.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiLineString.java
similarity index 53%
rename from src/com/esri/core/geometry/ogc/OGCMultiLineString.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCMultiLineString.java
index 2183020d..e0608f61 100644
--- a/src/com/esri/core/geometry/ogc/OGCMultiLineString.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCMultiLineString.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry.ogc;
import com.esri.core.geometry.GeoJsonExportFlags;
@@ -12,26 +36,37 @@
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.WkbExportFlags;
import com.esri.core.geometry.WktExportFlags;
+
import java.nio.ByteBuffer;
-public class OGCMultiLineString extends OGCMultiCurve {
+import static com.esri.core.geometry.SizeOf.SIZE_OF_OGC_MULTI_LINE_STRING;
+public class OGCMultiLineString extends OGCMultiCurve {
+ static public String TYPE = "MultiLineString";
+
public OGCMultiLineString(Polyline poly, SpatialReference sr) {
polyline = poly;
esriSR = sr;
}
+ public OGCMultiLineString(SpatialReference sr) {
+ polyline = new Polyline();
+ esriSR = sr;
+ }
+
@Override
public String asText() {
return GeometryEngine.geometryToWkt(getEsriGeometry(),
WktExportFlags.wktExportMultiLineString);
}
+
@Override
- public String asGeoJson() {
- OperatorExportToGeoJson op = (OperatorExportToGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToGeoJson);
- return op.execute(GeoJsonExportFlags.geoJsonExportPreferMultiGeometry, null, getEsriGeometry());
- }
+ public String asGeoJson() {
+ OperatorExportToGeoJson op = (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance()
+ .getOperator(Operator.Type.ExportToGeoJson);
+ return op.execute(GeoJsonExportFlags.geoJsonExportPreferMultiGeometry, esriSR, getEsriGeometry());
+ }
+
@Override
public ByteBuffer asBinary() {
OperatorExportToWkb op = (OperatorExportToWkb) OperatorFactoryLocal
@@ -48,7 +83,13 @@ public OGCGeometry geometryN(int n) {
@Override
public String geometryType() {
- return "MultiLineString";
+ return TYPE;
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_OGC_MULTI_LINE_STRING + (polyline != null ? polyline.estimateMemorySize() : 0);
}
@Override
@@ -76,5 +117,25 @@ public Geometry getEsriGeometry() {
return polyline;
}
+ @Override
+ public OGCGeometry convertToMulti()
+ {
+ return this;
+ }
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ int n = numGeometries();
+ if (n == 0) {
+ return new OGCLineString(new Polyline(polyline.getDescription()), 0, esriSR);
+ }
+
+ if (n == 1) {
+ return geometryN(0);
+ }
+
+ return this;
+ }
+
Polyline polyline;
}
diff --git a/src/com/esri/core/geometry/ogc/OGCMultiPoint.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiPoint.java
similarity index 64%
rename from src/com/esri/core/geometry/ogc/OGCMultiPoint.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCMultiPoint.java
index fa3f7c83..b1c70a02 100644
--- a/src/com/esri/core/geometry/ogc/OGCMultiPoint.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCMultiPoint.java
@@ -1,21 +1,47 @@
-package com.esri.core.geometry.ogc;
+/*
+ Copyright 1995-2017 Esri
-import java.nio.ByteBuffer;
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry.ogc;
import com.esri.core.geometry.Geometry;
-import com.esri.core.geometry.GeometryCursor;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.MultiPoint;
import com.esri.core.geometry.Operator;
import com.esri.core.geometry.OperatorExportToWkb;
import com.esri.core.geometry.OperatorFactoryLocal;
-import com.esri.core.geometry.OperatorUnion;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.WkbExportFlags;
import com.esri.core.geometry.WktExportFlags;
+import java.nio.ByteBuffer;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_OGC_MULTI_POINT;
+
public class OGCMultiPoint extends OGCGeometryCollection {
+ public static String TYPE = "MultiPoint";
+
public int numGeometries() {
return multiPoint.getPointCount();
}
@@ -41,7 +67,13 @@ public OGCGeometry geometryN(int n) {
@Override
public String geometryType() {
- return "MultiPoint";
+ return TYPE;
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_OGC_MULTI_POINT + (multiPoint != null ? multiPoint.estimateMemorySize() : 0);
}
/**
@@ -95,5 +127,25 @@ public Geometry getEsriGeometry() {
return multiPoint;
}
+ @Override
+ public OGCGeometry convertToMulti()
+ {
+ return this;
+ }
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ int n = numGeometries();
+ if (n == 0) {
+ return new OGCPoint(new Point(multiPoint.getDescription()), esriSR);
+ }
+
+ if (n == 1) {
+ return geometryN(0);
+ }
+
+ return this;
+ }
+
private com.esri.core.geometry.MultiPoint multiPoint;
}
diff --git a/src/com/esri/core/geometry/ogc/OGCMultiPolygon.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiPolygon.java
similarity index 62%
rename from src/com/esri/core/geometry/ogc/OGCMultiPolygon.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCMultiPolygon.java
index ac72df56..941bc7c2 100644
--- a/src/com/esri/core/geometry/ogc/OGCMultiPolygon.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCMultiPolygon.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry.ogc;
import com.esri.core.geometry.GeoJsonExportFlags;
@@ -12,15 +36,24 @@
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.WkbExportFlags;
import com.esri.core.geometry.WktExportFlags;
+
import java.nio.ByteBuffer;
-public class OGCMultiPolygon extends OGCMultiSurface {
+import static com.esri.core.geometry.SizeOf.SIZE_OF_OGC_MULTI_POLYGON;
+public class OGCMultiPolygon extends OGCMultiSurface {
+ static public String TYPE = "MultiPolygon";
+
public OGCMultiPolygon(Polygon src, SpatialReference sr) {
polygon = src;
esriSR = sr;
}
+ public OGCMultiPolygon(SpatialReference sr) {
+ polygon = new Polygon();
+ esriSR = sr;
+ }
+
@Override
public String asText() {
return GeometryEngine.geometryToWkt(getEsriGeometry(),
@@ -38,7 +71,7 @@ public ByteBuffer asBinary() {
public String asGeoJson() {
OperatorExportToGeoJson op = (OperatorExportToGeoJson) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.ExportToGeoJson);
- return op.execute(GeoJsonExportFlags.geoJsonExportPreferMultiGeometry, null, getEsriGeometry());
+ return op.execute(GeoJsonExportFlags.geoJsonExportPreferMultiGeometry, esriSR, getEsriGeometry());
}
@Override
public int numGeometries() {
@@ -52,7 +85,7 @@ public OGCGeometry geometryN(int n) {
if (polygon.isExteriorRing(i))
exterior++;
- if (exterior == i + 1) {
+ if (exterior == n + 1) {
return new OGCPolygon(polygon, i, esriSR);
}
}
@@ -62,7 +95,13 @@ public OGCGeometry geometryN(int n) {
@Override
public String geometryType() {
- return "MultiPolygon";
+ return TYPE;
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_OGC_MULTI_POLYGON + (polygon != null ? polygon.estimateMemorySize() : 0);
}
@Override
@@ -90,5 +129,25 @@ public Geometry getEsriGeometry() {
return polygon;
}
+ @Override
+ public OGCGeometry convertToMulti()
+ {
+ return this;
+ }
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ int n = numGeometries();
+ if (n == 0) {
+ return new OGCPolygon(new Polygon(polygon.getDescription()), 0, esriSR);
+ }
+
+ if (n == 1) {
+ return geometryN(0);
+ }
+
+ return this;
+ }
+
Polygon polygon;
}
diff --git a/src/com/esri/core/geometry/GeoJsonExportFlags.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiSurface.java
similarity index 71%
rename from src/com/esri/core/geometry/GeoJsonExportFlags.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCMultiSurface.java
index 04da23ce..5a36dd0e 100644
--- a/src/com/esri/core/geometry/GeoJsonExportFlags.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCMultiSurface.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,9 +21,16 @@
email: contracts@esri.com
*/
-package com.esri.core.geometry;
-public interface GeoJsonExportFlags {
- static final int geoJsonExportDefaults = 0;
- static final int geoJsonExportPreferMultiGeometry = 1;
+package com.esri.core.geometry.ogc;
+
+public abstract class OGCMultiSurface extends OGCGeometryCollection {
+ public double area() {
+ return getEsriGeometry().calculateArea2D();
+ }
+
+ public OGCPoint pointOnSurface() {
+ // TODO
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/src/com/esri/core/geometry/ogc/OGCPoint.java b/src/main/java/com/esri/core/geometry/ogc/OGCPoint.java
similarity index 60%
rename from src/com/esri/core/geometry/ogc/OGCPoint.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCPoint.java
index d04bbc62..d0fba6e7 100644
--- a/src/com/esri/core/geometry/ogc/OGCPoint.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCPoint.java
@@ -1,8 +1,29 @@
-package com.esri.core.geometry.ogc;
+/*
+ Copyright 1995-2018 Esri
-import java.nio.ByteBuffer;
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry.ogc;
-import com.esri.core.geometry.GeometryCursor;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.MultiPoint;
import com.esri.core.geometry.Operator;
@@ -13,7 +34,13 @@
import com.esri.core.geometry.WkbExportFlags;
import com.esri.core.geometry.WktExportFlags;
+import java.nio.ByteBuffer;
+
+import static com.esri.core.geometry.SizeOf.SIZE_OF_OGC_POINT;
+
public final class OGCPoint extends OGCGeometry {
+ public static String TYPE = "Point";
+
public OGCPoint(Point pt, SpatialReference sr) {
point = pt;
esriSR = sr;
@@ -51,7 +78,13 @@ public double M() {
@Override
public String geometryType() {
- return "Point";
+ return TYPE;
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_OGC_POINT + (point != null ? point.estimateMemorySize() : 0);
}
@Override
@@ -76,6 +109,17 @@ public OGCGeometry locateBetween(double mStart, double mEnd) {
public com.esri.core.geometry.Geometry getEsriGeometry() {
return point;
}
+
+ @Override
+ public OGCGeometry convertToMulti()
+ {
+ return new OGCMultiPoint(point, esriSR);
+ }
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ return this;
+ }
com.esri.core.geometry.Point point;
diff --git a/src/com/esri/core/geometry/ogc/OGCPolygon.java b/src/main/java/com/esri/core/geometry/ogc/OGCPolygon.java
similarity index 69%
rename from src/com/esri/core/geometry/ogc/OGCPolygon.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCPolygon.java
index e3613e3a..4c95250a 100644
--- a/src/com/esri/core/geometry/ogc/OGCPolygon.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCPolygon.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry.ogc;
import com.esri.core.geometry.Geometry;
@@ -10,9 +34,14 @@
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.WkbExportFlags;
import com.esri.core.geometry.WktExportFlags;
+
import java.nio.ByteBuffer;
+import static com.esri.core.geometry.SizeOf.SIZE_OF_OGC_POLYGON;
+
public class OGCPolygon extends OGCSurface {
+ public static String TYPE = "Polygon";
+
public OGCPolygon(Polygon src, int exteriorRing, SpatialReference sr) {
polygon = new Polygon();
for (int i = exteriorRing, n = src.getPathCount(); i < n; i++) {
@@ -49,7 +78,7 @@ public ByteBuffer asBinary() {
* Returns the exterior ring of this Polygon.
* @return OGCLinearRing instance.
*/
- public OGCLineString exterorRing() {
+ public OGCLineString exteriorRing() {
if (polygon.isEmpty())
return new OGCLinearRing((Polygon) polygon.createInstance(), 0,
esriSR, true);
@@ -82,7 +111,13 @@ public OGCMultiCurve boundary() {
@Override
public String geometryType() {
- return "Polygon";
+ return TYPE;
+ }
+
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_OGC_POLYGON + (polygon != null ? polygon.estimateMemorySize() : 0);
}
@Override
@@ -102,5 +137,16 @@ public Geometry getEsriGeometry() {
return polygon;
}
+ @Override
+ public OGCGeometry convertToMulti()
+ {
+ return new OGCMultiPolygon(polygon, esriSR);
+ }
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ return this;
+ }
+
Polygon polygon;
}
diff --git a/src/com/esri/core/geometry/GeoJsonImportFlags.java b/src/main/java/com/esri/core/geometry/ogc/OGCSurface.java
similarity index 66%
rename from src/com/esri/core/geometry/GeoJsonImportFlags.java
rename to src/main/java/com/esri/core/geometry/ogc/OGCSurface.java
index e2539151..989dfec8 100644
--- a/src/com/esri/core/geometry/GeoJsonImportFlags.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCSurface.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,9 +21,19 @@
email: contracts@esri.com
*/
-package com.esri.core.geometry;
-public interface GeoJsonImportFlags {
- static final int geoJsonImportDefaults = 0;
- static final int geoJsonImportNonTrusted = 2;
+package com.esri.core.geometry.ogc;
+
+public abstract class OGCSurface extends OGCGeometry {
+ public double area() {
+ return getEsriGeometry().calculateArea2D();
+ }
+
+ public OGCPoint pointOnSurface() {
+ // TODO: support this (need to port OperatorLabelPoint)
+ throw new UnsupportedOperationException();
+ }
+
+ public abstract OGCMultiCurve boundary();
+
}
diff --git a/src/main/java/com/esri/core/geometry/ogc/package-info.java b/src/main/java/com/esri/core/geometry/ogc/package-info.java
new file mode 100644
index 00000000..b6b69aa6
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/ogc/package-info.java
@@ -0,0 +1,19 @@
+/*
+ Copyright 2017-2023 Esri
+
+ Licensed 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.
+ */
+
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("2.2.4")
+package com.esri.core.geometry.ogc;
diff --git a/src/main/java/com/esri/core/geometry/package-info.java b/src/main/java/com/esri/core/geometry/package-info.java
new file mode 100644
index 00000000..5a613f65
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/package-info.java
@@ -0,0 +1,19 @@
+/*
+ Copyright 2017-2023 Esri
+
+ Licensed 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.
+ */
+
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("2.2.4")
+package com.esri.core.geometry;
diff --git a/src/com/esri/core/geometry/gcs_id_to_tolerance.txt b/src/main/resources/com/esri/core/geometry/gcs_id_to_tolerance.txt
similarity index 100%
rename from src/com/esri/core/geometry/gcs_id_to_tolerance.txt
rename to src/main/resources/com/esri/core/geometry/gcs_id_to_tolerance.txt
diff --git a/src/com/esri/core/geometry/gcs_tolerances.txt b/src/main/resources/com/esri/core/geometry/gcs_tolerances.txt
similarity index 100%
rename from src/com/esri/core/geometry/gcs_tolerances.txt
rename to src/main/resources/com/esri/core/geometry/gcs_tolerances.txt
diff --git a/src/com/esri/core/geometry/intermediate_to_old_wkid.txt b/src/main/resources/com/esri/core/geometry/intermediate_to_old_wkid.txt
similarity index 100%
rename from src/com/esri/core/geometry/intermediate_to_old_wkid.txt
rename to src/main/resources/com/esri/core/geometry/intermediate_to_old_wkid.txt
diff --git a/src/com/esri/core/geometry/new_to_old_wkid.txt b/src/main/resources/com/esri/core/geometry/new_to_old_wkid.txt
similarity index 99%
rename from src/com/esri/core/geometry/new_to_old_wkid.txt
rename to src/main/resources/com/esri/core/geometry/new_to_old_wkid.txt
index 7cb8d997..86477d47 100644
--- a/src/com/esri/core/geometry/new_to_old_wkid.txt
+++ b/src/main/resources/com/esri/core/geometry/new_to_old_wkid.txt
@@ -284,6 +284,7 @@
3775 102186
3776 102187
3777 102188
+3785 102113
3800 102183
3801 102189
3812 102199
diff --git a/src/com/esri/core/geometry/pcs_id_to_tolerance.txt b/src/main/resources/com/esri/core/geometry/pcs_id_to_tolerance.txt
similarity index 99%
rename from src/com/esri/core/geometry/pcs_id_to_tolerance.txt
rename to src/main/resources/com/esri/core/geometry/pcs_id_to_tolerance.txt
index f38609e5..e4386fc5 100644
--- a/src/com/esri/core/geometry/pcs_id_to_tolerance.txt
+++ b/src/main/resources/com/esri/core/geometry/pcs_id_to_tolerance.txt
@@ -3126,6 +3126,7 @@
102110 3
102111 3
102112 3
+102113 3
102114 3
102115 3
102116 3
diff --git a/src/com/esri/core/geometry/pcs_tolerances.txt b/src/main/resources/com/esri/core/geometry/pcs_tolerances.txt
similarity index 100%
rename from src/com/esri/core/geometry/pcs_tolerances.txt
rename to src/main/resources/com/esri/core/geometry/pcs_tolerances.txt
diff --git a/src/test/java/com/esri/core/geometry/GeometryUtils.java b/src/test/java/com/esri/core/geometry/GeometryUtils.java
new file mode 100644
index 00000000..2734db7c
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/GeometryUtils.java
@@ -0,0 +1,125 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+public class GeometryUtils {
+ public static String getGeometryType(Geometry geomIn) {
+ // there are five types: esriGeometryPoint
+ // esriGeometryMultipoint
+ // esriGeometryPolyline
+ // esriGeometryPolygon
+ // esriGeometryEnvelope
+ if (geomIn instanceof Point)
+ return "esriGeometryPoint";
+ if (geomIn instanceof MultiPoint)
+ return "esriGeometryMultipoint";
+ if (geomIn instanceof Polyline)
+ return "esriGeometryPolyline";
+ if (geomIn instanceof Polygon)
+ return "esriGeometryPolygon";
+ if (geomIn instanceof Envelope)
+ return "esriGeometryEnvelope";
+ else
+ return null;
+ }
+
+ static Geometry getGeometryFromJSon(String jsonStr) {
+ try {
+ Geometry geom = GeometryEngine.jsonToGeometry(jsonStr).getGeometry();
+ return geom;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public enum SpatialRelationType {
+ esriGeometryRelationCross, esriGeometryRelationDisjoint, esriGeometryRelationIn, esriGeometryRelationInteriorIntersection, esriGeometryRelationIntersection, esriGeometryRelationLineCoincidence, esriGeometryRelationLineTouch, esriGeometryRelationOverlap, esriGeometryRelationPointTouch, esriGeometryRelationTouch, esriGeometryRelationWithin, esriGeometryRelationRelation
+ }
+
+ static String getJSonStringFromGeometry(Geometry geomIn, SpatialReference sr) {
+ String jsonStr4Geom = GeometryEngine.geometryToJson(sr, geomIn);
+ String jsonStrNew = "{\"geometryType\":\"" + getGeometryType(geomIn)
+ + "\",\"geometries\":[" + jsonStr4Geom + "]}";
+ return jsonStrNew;
+ }
+
+ public static Geometry loadFromTextFileDbg(String textFileName)
+ throws FileNotFoundException {
+ String fullPath = textFileName;
+ // string fullCSVPathName = System.IO.Path.Combine( directoryPath ,
+ // CsvFileName);
+ File fileInfo = new File(fullPath);
+
+ Scanner scanner = new Scanner(fileInfo);
+
+ Geometry geom = null;
+
+ // grab first line
+ String line = scanner.nextLine();
+ String geomTypeString = line.substring(1);
+ if (geomTypeString.equalsIgnoreCase("polygon"))
+ geom = new Polygon();
+ else if (geomTypeString.equalsIgnoreCase("polyline"))
+ geom = new Polyline();
+ else if (geomTypeString.equalsIgnoreCase("multipoint"))
+ geom = new MultiPoint();
+ else if (geomTypeString.equalsIgnoreCase("point"))
+ geom = new Point();
+
+ while (line.startsWith("*"))
+ if (scanner.hasNextLine())
+ line = scanner.nextLine();
+
+ int j = 0;
+ Geometry.Type geomType = geom.getType();
+ while (scanner.hasNextLine()) {
+ String[] parsedLine = line.split("\\s+");
+ double xVal = Double.parseDouble(parsedLine[0]);
+ double yVal = Double.parseDouble(parsedLine[1]);
+ if (j == 0
+ && (geomType == Geometry.Type.Polygon || geomType == Geometry.Type.Polyline))
+ ((MultiPath) geom).startPath(xVal, yVal);
+ else {
+ if (geomType == Geometry.Type.Polygon
+ || geomType == Geometry.Type.Polyline)
+ ((MultiPath) geom).lineTo(xVal, yVal);
+ else if (geomType == Geometry.Type.MultiPoint)
+ ((MultiPoint) geom).add(xVal, yVal);
+ // else if(geomType == Geometry.Type.Point)
+ // Point geom = null;//new Point(xVal, yVal);
+ }
+ j++;
+ line = scanner.nextLine();
+ }
+
+ scanner.close();
+
+ return geom;
+ }
+}
diff --git a/unittest/com/esri/core/geometry/RandomCoordinateGenerator.java b/src/test/java/com/esri/core/geometry/RandomCoordinateGenerator.java
similarity index 94%
rename from unittest/com/esri/core/geometry/RandomCoordinateGenerator.java
rename to src/test/java/com/esri/core/geometry/RandomCoordinateGenerator.java
index f50f12d7..dcaa0444 100644
--- a/unittest/com/esri/core/geometry/RandomCoordinateGenerator.java
+++ b/src/test/java/com/esri/core/geometry/RandomCoordinateGenerator.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import java.util.Random;
diff --git a/src/test/java/com/esri/core/geometry/TestAttributes.java b/src/test/java/com/esri/core/geometry/TestAttributes.java
new file mode 100644
index 00000000..16c1d9df
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestAttributes.java
@@ -0,0 +1,349 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import static org.junit.Assert.*;
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+public class TestAttributes extends TestCase{
+
+ @Test
+ public void testPoint() {
+ Point pt = new Point();
+ pt.setXY(100, 200);
+ assertFalse(pt.hasAttribute(VertexDescription.Semantics.M));
+ pt.addAttribute(VertexDescription.Semantics.M);
+ assertTrue(pt.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(Double.isNaN(pt.getM()));
+ pt.setAttribute(VertexDescription.Semantics.M, 0, 13);
+ assertTrue(pt.getM() == 13);
+ pt.addAttribute(VertexDescription.Semantics.Z);
+ assertTrue(pt.getZ() == 0);
+ assertTrue(pt.getM() == 13);
+ pt.setAttribute(VertexDescription.Semantics.Z, 0, 11);
+ assertTrue(pt.getZ() == 11);
+ assertTrue(pt.getM() == 13);
+ pt.addAttribute(VertexDescription.Semantics.ID);
+ assertTrue(pt.getID() == 0);
+ assertTrue(pt.getZ() == 11);
+ assertTrue(pt.getM() == 13);
+ pt.setAttribute(VertexDescription.Semantics.ID, 0, 1);
+ assertTrue(pt.getID() == 1);
+ assertTrue(pt.getZ() == 11);
+ assertTrue(pt.getM() == 13);
+ pt.dropAttribute(VertexDescription.Semantics.M);
+ assertTrue(pt.getID() == 1);
+ assertTrue(pt.getZ() == 11);
+ assertFalse(pt.hasAttribute(VertexDescription.Semantics.M));
+
+ Point pt1 = new Point();
+ assertFalse(pt1.hasAttribute(VertexDescription.Semantics.M));
+ assertFalse(pt1.hasAttribute(VertexDescription.Semantics.Z));
+ assertFalse(pt1.hasAttribute(VertexDescription.Semantics.ID));
+ pt1.mergeVertexDescription(pt.getDescription());
+ assertFalse(pt1.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(pt1.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(pt1.hasAttribute(VertexDescription.Semantics.ID));
+ }
+
+ @Test
+ public void testEnvelope() {
+ Envelope env = new Envelope();
+ env.setCoords(100, 200, 250, 300);
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.M));
+ env.addAttribute(VertexDescription.Semantics.M);
+ assertTrue(env.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(env.queryInterval(VertexDescription.Semantics.M, 0).isEmpty());
+ env.setInterval(VertexDescription.Semantics.M, 0, 1, 2);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.M, 0).vmin == 1);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.M, 0).vmax == 2);
+
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.Z));
+ env.addAttribute(VertexDescription.Semantics.Z);
+ assertTrue(env.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmin == 0);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmax == 0);
+ env.setInterval(VertexDescription.Semantics.Z, 0, 3, 4);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmin == 3);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmax == 4);
+
+
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.ID));
+ env.addAttribute(VertexDescription.Semantics.ID);
+ assertTrue(env.hasAttribute(VertexDescription.Semantics.ID));
+ assertTrue(env.queryInterval(VertexDescription.Semantics.ID, 0).vmin == 0);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.ID, 0).vmax == 0);
+ env.setInterval(VertexDescription.Semantics.ID, 0, 5, 6);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.ID, 0).vmin == 5);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.ID, 0).vmax == 6);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmin == 3);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmax == 4);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.M, 0).vmin == 1);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.M, 0).vmax == 2);
+
+ env.dropAttribute(VertexDescription.Semantics.M);
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(env.queryInterval(VertexDescription.Semantics.ID, 0).vmin == 5);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.ID, 0).vmax == 6);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmin == 3);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).vmax == 4);
+
+ Envelope env1 = new Envelope();
+ env.copyTo(env1);
+ assertFalse(env1.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(env1.queryInterval(VertexDescription.Semantics.ID, 0).vmin == 5);
+ assertTrue(env1.queryInterval(VertexDescription.Semantics.ID, 0).vmax == 6);
+ assertTrue(env1.queryInterval(VertexDescription.Semantics.Z, 0).vmin == 3);
+ assertTrue(env1.queryInterval(VertexDescription.Semantics.Z, 0).vmax == 4);
+ }
+
+ @Test
+ public void testLine() {
+ Line env = new Line();
+ env.setStartXY(100, 200);
+ env.setEndXY(250, 300);
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.M));
+ env.addAttribute(VertexDescription.Semantics.M);
+ assertTrue(env.hasAttribute(VertexDescription.Semantics.M));
+ env.setStartAttribute(VertexDescription.Semantics.M, 0, 1);
+ env.setEndAttribute(VertexDescription.Semantics.M, 0, 2);
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.M, 0) == 1);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.M, 0) == 2);
+
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.Z));
+ env.addAttribute(VertexDescription.Semantics.Z);
+ assertTrue(env.hasAttribute(VertexDescription.Semantics.Z));
+ env.setStartAttribute(VertexDescription.Semantics.Z, 0, 3);
+ env.setEndAttribute(VertexDescription.Semantics.Z, 0, 4);
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 3);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 4);
+
+
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.ID));
+ env.addAttribute(VertexDescription.Semantics.ID);
+ assertTrue(env.hasAttribute(VertexDescription.Semantics.ID));
+ env.setStartAttribute(VertexDescription.Semantics.ID, 0, 5);
+ env.setEndAttribute(VertexDescription.Semantics.ID, 0, 6);
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.ID, 0) == 5);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.ID, 0) == 6);
+
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.M, 0) == 1);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.M, 0) == 2);
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 3);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 4);
+
+ env.dropAttribute(VertexDescription.Semantics.M);
+ assertFalse(env.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.ID, 0) == 5);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.ID, 0) == 6);
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 3);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 4);
+
+ Line env1 = new Line();
+ env.copyTo(env1);
+ assertFalse(env1.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.ID, 0) == 5);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.ID, 0) == 6);
+ assertTrue(env.getStartAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 3);
+ assertTrue(env.getEndAttributeAsDbl(VertexDescription.Semantics.Z, 0) == 4);
+ }
+
+ @Test
+ public void testMultiPoint() {
+ MultiPoint mp = new MultiPoint();
+ mp.add(new Point(100, 200));
+ mp.add(new Point(101, 201));
+ mp.add(new Point(102, 202));
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.M));
+ mp.addAttribute(VertexDescription.Semantics.M);
+ assertTrue(mp.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(Double.isNaN(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)));
+ assertTrue(Double.isNaN(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)));
+ assertTrue(Double.isNaN(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)));
+ mp.setAttribute(VertexDescription.Semantics.M, 0, 0, 1);
+ mp.setAttribute(VertexDescription.Semantics.M, 1, 0, 2);
+ mp.setAttribute(VertexDescription.Semantics.M, 2, 0, 3);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)==1);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)==2);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)==3);
+
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.Z));
+ mp.addAttribute(VertexDescription.Semantics.Z);
+ assertTrue(mp.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==0);
+ mp.setAttribute(VertexDescription.Semantics.Z, 0, 0, 11);
+ mp.setAttribute(VertexDescription.Semantics.Z, 1, 0, 21);
+ mp.setAttribute(VertexDescription.Semantics.Z, 2, 0, 31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)==1);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)==2);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)==3);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.ID));
+ mp.addAttribute(VertexDescription.Semantics.ID);
+ assertTrue(mp.hasAttribute(VertexDescription.Semantics.ID));
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==0);
+ mp.setAttribute(VertexDescription.Semantics.ID, 0, 0, -11);
+ mp.setAttribute(VertexDescription.Semantics.ID, 1, 0, -21);
+ mp.setAttribute(VertexDescription.Semantics.ID, 2, 0, -31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)==1);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)==2);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)==3);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==-11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==-21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==-31);
+
+ mp.dropAttribute(VertexDescription.Semantics.M);
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==-11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==-21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==-31);
+
+ MultiPoint mp1 = new MultiPoint();
+ mp.copyTo(mp1);
+ assertFalse(mp1.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==-11);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==-21);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==-31);
+
+ mp1.dropAllAttributes();
+ mp1.mergeVertexDescription(mp.getDescription());
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==0);
+ assertTrue(Double.isNaN(mp1.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)));
+ assertTrue(Double.isNaN(mp1.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)));
+ assertTrue(Double.isNaN(mp1.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)));
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==0);
+
+ }
+
+ @Test
+ public void testPolygon() {
+ Polygon mp = new Polygon();
+ mp.startPath(new Point(100, 200));
+ mp.lineTo(new Point(101, 201));
+ mp.lineTo(new Point(102, 202));
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.M));
+ mp.addAttribute(VertexDescription.Semantics.M);
+ assertTrue(mp.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(Double.isNaN(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)));
+ assertTrue(Double.isNaN(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)));
+ assertTrue(Double.isNaN(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)));
+ mp.setAttribute(VertexDescription.Semantics.M, 0, 0, 1);
+ mp.setAttribute(VertexDescription.Semantics.M, 1, 0, 2);
+ mp.setAttribute(VertexDescription.Semantics.M, 2, 0, 3);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)==1);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)==2);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)==3);
+
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.Z));
+ mp.addAttribute(VertexDescription.Semantics.Z);
+ assertTrue(mp.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==0);
+ mp.setAttribute(VertexDescription.Semantics.Z, 0, 0, 11);
+ mp.setAttribute(VertexDescription.Semantics.Z, 1, 0, 21);
+ mp.setAttribute(VertexDescription.Semantics.Z, 2, 0, 31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)==1);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)==2);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)==3);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.ID));
+ mp.addAttribute(VertexDescription.Semantics.ID);
+ assertTrue(mp.hasAttribute(VertexDescription.Semantics.ID));
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==0);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==0);
+ mp.setAttribute(VertexDescription.Semantics.ID, 0, 0, -11);
+ mp.setAttribute(VertexDescription.Semantics.ID, 1, 0, -21);
+ mp.setAttribute(VertexDescription.Semantics.ID, 2, 0, -31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)==1);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)==2);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)==3);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==-11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==-21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==-31);
+
+ mp.dropAttribute(VertexDescription.Semantics.M);
+ assertFalse(mp.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==-11);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==-21);
+ assertTrue(mp.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==-31);
+
+ Polygon mp1 = new Polygon();
+ mp.copyTo(mp1);
+ assertFalse(mp1.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==11);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==21);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==31);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==-11);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==-21);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==-31);
+
+ mp1.dropAllAttributes();
+ mp1.mergeVertexDescription(mp.getDescription());
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 1, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.Z, 2, 0)==0);
+ assertTrue(Double.isNaN(mp1.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0)));
+ assertTrue(Double.isNaN(mp1.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0)));
+ assertTrue(Double.isNaN(mp1.getAttributeAsDbl(VertexDescription.Semantics.M, 2, 0)));
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0)==0);
+ assertTrue(mp1.getAttributeAsDbl(VertexDescription.Semantics.ID, 2, 0)==0);
+
+ }
+
+}
diff --git a/unittest/com/esri/core/geometry/TestBuffer.java b/src/test/java/com/esri/core/geometry/TestBuffer.java
old mode 100644
new mode 100755
similarity index 86%
rename from unittest/com/esri/core/geometry/TestBuffer.java
rename to src/test/java/com/esri/core/geometry/TestBuffer.java
index 38902f83..e60145bb
--- a/unittest/com/esri/core/geometry/TestBuffer.java
+++ b/src/test/java/com/esri/core/geometry/TestBuffer.java
@@ -1,8 +1,34 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
import org.junit.Test;
+import com.esri.core.geometry.ogc.OGCGeometry;
+
public class TestBuffer extends TestCase {
@Override
protected void setUp() throws Exception {
@@ -266,6 +292,17 @@ public void testBufferPolyline() {
assertTrue(Math.abs(pointCount - 208.0) < 10);
assertTrue(simplify.isSimpleAsFeature(result, sr, null));
}
+
+ {
+ inputGeom = new Polyline();
+ inputGeom.startPath(1.762614,0.607368);
+ inputGeom.lineTo(1.762414,0.606655);
+ inputGeom.lineTo(1.763006,0.607034);
+ inputGeom.lineTo(1.762548,0.607135);
+
+ Geometry result = buffer.execute(inputGeom, sr, 0.005, null);
+ assertTrue(simplify.isSimpleAsFeature(result, sr, null));
+ }
}
@Test
@@ -354,4 +391,27 @@ public void testBufferPolygon() {
assertTrue(simplify.isSimpleAsFeature(result, sr, null));
}
}
+
+ @Test
+ public static void testTinyBufferOfPoint() {
+ {
+ Geometry result1 = OperatorBuffer.local().execute(new Point(0, 0), SpatialReference.create(4326), 1e-9, null);
+ assertTrue(result1 != null);
+ assertTrue(result1.isEmpty());
+ Geometry geom1 = OperatorImportFromWkt.local().execute(0, Geometry.Type.Unknown, "POLYGON ((177.0 64.0, 177.0000000001 64.0, 177.0000000001 64.0000000001, 177.0 64.0000000001, 177.0 64.0))", null);
+ Geometry result2 = OperatorBuffer.local().execute(geom1, SpatialReference.create(4326), 0.01, null);
+ assertTrue(result2 != null);
+ assertTrue(result2.isEmpty());
+
+ }
+
+ {
+ OGCGeometry p = OGCGeometry.fromText(
+ "POLYGON ((177.0 64.0, 177.0000000001 64.0, 177.0000000001 64.0000000001, 177.0 64.0000000001, 177.0 64.0))");
+ OGCGeometry buffered = p.buffer(0.01);
+ assertTrue(buffered != null);
+ }
+
+
+ }
}
diff --git a/src/test/java/com/esri/core/geometry/TestCentroid.java b/src/test/java/com/esri/core/geometry/TestCentroid.java
new file mode 100644
index 00000000..3065ec9e
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestCentroid.java
@@ -0,0 +1,169 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestCentroid {
+ @Test
+ public void testPoint() {
+ assertCentroid(new Point(1, 2), new Point2D(1, 2));
+ }
+
+ @Test
+ public void testLine() {
+ assertCentroid(new Line(0, 0, 10, 20), new Point2D(5, 10));
+ }
+
+ @Test
+ public void testEnvelope() {
+ assertCentroid(new Envelope(1, 2, 3, 4), new Point2D(2, 3));
+ assertCentroidEmpty(new Envelope());
+ }
+
+ @Test
+ public void testMultiPoint() {
+ MultiPoint multiPoint = new MultiPoint();
+ multiPoint.add(0, 0);
+ multiPoint.add(1, 2);
+ multiPoint.add(3, 1);
+ multiPoint.add(0, 1);
+
+ assertCentroid(multiPoint, new Point2D(1, 1));
+ assertCentroidEmpty(new MultiPoint());
+ }
+
+ @Test
+ public void testPolyline() {
+ Polyline polyline = new Polyline();
+ polyline.startPath(0, 0);
+ polyline.lineTo(1, 2);
+ polyline.lineTo(3, 4);
+ assertCentroid(polyline, new Point2D(1.3377223398316207, 2.1169631197754946));
+
+ polyline.startPath(1, -1);
+ polyline.lineTo(2, 0);
+ polyline.lineTo(10, 1);
+ assertCentroid(polyline, new Point2D(3.93851092460519, 0.9659173294165462));
+
+ assertCentroidEmpty(new Polyline());
+ }
+
+ @Test
+ public void testPolygon() {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(1, 2);
+ polygon.lineTo(3, 4);
+ polygon.lineTo(5, 2);
+ polygon.lineTo(0, 0);
+ assertCentroid(polygon, new Point2D(2.5, 2));
+
+ // add a hole
+ polygon.startPath(2, 2);
+ polygon.lineTo(2.3, 2);
+ polygon.lineTo(2.3, 2.4);
+ polygon.lineTo(2, 2);
+ assertCentroid(polygon, new Point2D(2.5022670025188916, 1.9989924433249369));
+
+ // add another polygon
+ polygon.startPath(-1, -1);
+ polygon.lineTo(3, -1);
+ polygon.lineTo(0.5, -2);
+ polygon.lineTo(-1, -1);
+ assertCentroid(polygon, new Point2D(2.166465459423206, 1.3285043594902748));
+
+ assertCentroidEmpty(new Polygon());
+ }
+
+ @Test
+ public void testSmallPolygon() {
+ // https://github.com/Esri/geometry-api-java/issues/225
+
+ Polygon polygon = new Polygon();
+ polygon.startPath(153.492818, -28.13729);
+ polygon.lineTo(153.492821, -28.137291);
+ polygon.lineTo(153.492816, -28.137289);
+ polygon.lineTo(153.492818, -28.13729);
+
+ assertCentroid(polygon, new Point2D(153.492818333333333, -28.13729));
+ }
+
+ @Test
+ public void testZeroAreaPolygon() {
+ Polygon polygon = new Polygon();
+ polygon.startPath(153, 28);
+ polygon.lineTo(163, 28);
+ polygon.lineTo(153, 28);
+
+ Polyline polyline = (Polyline) polygon.getBoundary();
+ Point2D expectedCentroid = new Point2D(158, 28);
+
+ assertCentroid(polyline, expectedCentroid);
+ assertCentroid(polygon, expectedCentroid);
+ }
+
+ @Test
+ public void testDegeneratesToPointPolygon() {
+ Polygon polygon = new Polygon();
+ polygon.startPath(-8406364, 560828);
+ polygon.lineTo(-8406364, 560828);
+ polygon.lineTo(-8406364, 560828);
+ polygon.lineTo(-8406364, 560828);
+
+ assertCentroid(polygon, new Point2D(-8406364, 560828));
+ }
+
+ @Test
+ public void testZeroLengthPolyline() {
+ Polyline polyline = new Polyline();
+ polyline.startPath(153, 28);
+ polyline.lineTo(153, 28);
+
+ assertCentroid(polyline, new Point2D(153, 28));
+ }
+
+ @Test
+ public void testDegeneratesToPointPolyline() {
+ Polyline polyline = new Polyline();
+ polyline.startPath(-8406364, 560828);
+ polyline.lineTo(-8406364, 560828);
+
+ assertCentroid(polyline, new Point2D(-8406364, 560828));
+ }
+
+ private static void assertCentroid(Geometry geometry, Point2D expectedCentroid) {
+
+ Point2D actualCentroid = OperatorCentroid2D.local().execute(geometry, null);
+ Assert.assertEquals(expectedCentroid.x, actualCentroid.x, 1e-13);
+ Assert.assertEquals(expectedCentroid.y, actualCentroid.y, 1e-13);
+ }
+
+ private static void assertCentroidEmpty(Geometry geometry) {
+
+ Point2D actualCentroid = OperatorCentroid2D.local().execute(geometry, null);
+ Assert.assertTrue(actualCentroid == null);
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestClip.java b/src/test/java/com/esri/core/geometry/TestClip.java
similarity index 92%
rename from unittest/com/esri/core/geometry/TestClip.java
rename to src/test/java/com/esri/core/geometry/TestClip.java
index ee8d675f..3dcca075 100644
--- a/unittest/com/esri/core/geometry/TestClip.java
+++ b/src/test/java/com/esri/core/geometry/TestClip.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
@@ -107,8 +131,7 @@ public static void testClipGeometries() {
}
}
- @Test
- public static Polygon makePolygon() {
+ static Polygon makePolygon() {
Polygon poly = new Polygon();
poly.startPath(0, 0);
poly.lineTo(10, 10);
@@ -117,8 +140,7 @@ public static Polygon makePolygon() {
return poly;
}
- @Test
- public static Polyline makePolyline() {
+ static Polyline makePolyline() {
Polyline poly = new Polyline();
poly.startPath(0, 0);
poly.lineTo(10, 10);
@@ -185,8 +207,7 @@ public static void testArcObjectsFailureCR196492() {
// ((MultiPathImpl::SPtr)clippedPolygon._GetImpl()).SaveToTextFileDbg("c:\\temp\\test_ArcObjects_failure_CR196492.txt");
}
- @Test
- public static Polyline makePolylineCR() {
+ static Polyline makePolylineCR() {
Polyline polyline = new Polyline();
polyline.startPath(-200, -90);
@@ -200,8 +221,7 @@ public static Polyline makePolylineCR() {
return polyline;
}
- @Test
- public static MultiPoint makeMultiPoint() {
+ static MultiPoint makeMultiPoint() {
MultiPoint mpoint = new MultiPoint();
Point2D pt1 = new Point2D();
@@ -223,8 +243,7 @@ public static MultiPoint makeMultiPoint() {
return mpoint;
}
- @Test
- public static Point makePoint() {
+ static Point makePoint() {
Point point = new Point();
Point2D pt = new Point2D();
diff --git a/unittest/com/esri/core/geometry/TestCommonMethods.java b/src/test/java/com/esri/core/geometry/TestCommonMethods.java
similarity index 89%
rename from unittest/com/esri/core/geometry/TestCommonMethods.java
rename to src/test/java/com/esri/core/geometry/TestCommonMethods.java
index 420718d4..9b937d4b 100644
--- a/unittest/com/esri/core/geometry/TestCommonMethods.java
+++ b/src/test/java/com/esri/core/geometry/TestCommonMethods.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import java.io.File;
@@ -5,8 +29,6 @@
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParser;
import junit.framework.TestCase;
import org.junit.Test;
@@ -237,15 +259,8 @@ public static Object readObjectFromFile(String fileName) {
}
public static MapGeometry fromJson(String jsonString) {
- JsonFactory factory = new JsonFactory();
try {
- JsonParser jsonParser = factory.createJsonParser(jsonString);
- jsonParser.nextToken();
- OperatorImportFromJson importer = (OperatorImportFromJson) OperatorFactoryLocal
- .getInstance().getOperator(
- Operator.Type.ImportFromJson);
-
- return importer.execute(Geometry.Type.Unknown, jsonParser);
+ return OperatorImportFromJson.local().execute(Geometry.Type.Unknown, jsonString);
} catch (Exception ex) {
}
diff --git a/unittest/com/esri/core/geometry/TestContains.java b/src/test/java/com/esri/core/geometry/TestContains.java
similarity index 80%
rename from unittest/com/esri/core/geometry/TestContains.java
rename to src/test/java/com/esri/core/geometry/TestContains.java
index 71c811e9..d6da4af7 100644
--- a/unittest/com/esri/core/geometry/TestContains.java
+++ b/src/test/java/com/esri/core/geometry/TestContains.java
@@ -1,12 +1,39 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
-import java.io.IOException;
import junit.framework.TestCase;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
+
+import java.io.IOException;
+
import org.junit.Test;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+
public class TestContains extends TestCase {
@Override
protected void setUp() throws Exception {
@@ -19,11 +46,10 @@ protected void tearDown() throws Exception {
}
@Test
- public static void testContainsFailureCR186456() throws JsonParseException,
- IOException {
+ public static void testContainsFailureCR186456() throws JsonParseException, IOException {
String str = "{\"rings\":[[[406944.399999999,287461.450000001],[406947.750000011,287462.299999997],[406946.44999999,287467.450000001],[406943.050000005,287466.550000005],[406927.799999992,287456.849999994],[406926.949999996,287456.599999995],[406924.800000005,287455.999999998],[406924.300000007,287455.849999999],[406924.200000008,287456.099999997],[406923.450000011,287458.449999987],[406922.999999987,287459.800000008],[406922.29999999,287462.099999998],[406921.949999991,287463.449999992],[406921.449999993,287465.050000011],[406920.749999996,287466.700000004],[406919.800000001,287468.599999996],[406919.050000004,287469.99999999],[406917.800000009,287471.800000008],[406916.04999999,287473.550000001],[406915.449999993,287473.999999999],[406913.700000001,287475.449999993],[406913.300000002,287475.899999991],[406912.050000008,287477.250000011],[406913.450000002,287478.150000007],[406915.199999994,287478.650000005],[406915.999999991,287478.800000005],[406918.300000007,287479.200000003],[406920.649999997,287479.450000002],[406923.100000013,287479.550000001],[406925.750000001,287479.450000002],[406928.39999999,287479.150000003],[406929.80000001,287478.950000004],[406932.449999998,287478.350000006],[406935.099999987,287477.60000001],[406938.699999998,287476.349999989],[406939.649999994,287473.949999999],[406939.799999993,287473.949999999],[406941.249999987,287473.75],[406942.700000007,287473.250000002],[406943.100000005,287473.100000003],[406943.950000001,287472.750000004],[406944.799999998,287472.300000006],[406944.999999997,287472.200000007],[406946.099999992,287471.200000011],[406946.299999991,287470.950000012],[406948.00000001,287468.599999996],[406948.10000001,287468.399999997],[406950.100000001,287465.050000011],[406951.949999993,287461.450000001],[406952.049999993,287461.300000001],[406952.69999999,287459.900000007],[406953.249999987,287458.549999987],[406953.349999987,287458.299999988],[406953.650000012,287457.299999992],[406953.900000011,287456.349999996],[406954.00000001,287455.300000001],[406954.00000001,287454.750000003],[406953.850000011,287453.750000008],[406953.550000012,287452.900000011],[406953.299999987,287452.299999988],[406954.500000008,287450.299999996],[406954.00000001,287449.000000002],[406953.399999987,287447.950000006],[406953.199999988,287447.550000008],[406952.69999999,287446.850000011],[406952.149999992,287446.099999988],[406951.499999995,287445.499999991],[406951.149999996,287445.249999992],[406950.449999999,287444.849999994],[406949.600000003,287444.599999995],[406949.350000004,287444.549999995],[406948.250000009,287444.499999995],[406947.149999987,287444.699999994],[406946.849999989,287444.749999994],[406945.899999993,287444.949999993],[406944.999999997,287445.349999991],[406944.499999999,287445.64999999],[406943.650000003,287446.349999987],[406942.900000006,287447.10000001],[406942.500000008,287447.800000007],[406942.00000001,287448.700000003],[406941.600000011,287449.599999999],[406941.350000013,287450.849999994],[406941.350000013,287451.84999999],[406941.450000012,287452.850000012],[406941.750000011,287453.850000007],[406941.800000011,287454.000000007],[406942.150000009,287454.850000003],[406942.650000007,287455.6],[406943.150000005,287456.299999997],[406944.499999999,287457.299999992],[406944.899999997,287457.599999991],[406945.299999995,287457.949999989],[406944.399999999,287461.450000001],[406941.750000011,287461.999999998],[406944.399999999,287461.450000001]],[[406944.399999999,287461.450000001],[406947.750000011,287462.299999997],[406946.44999999,287467.450000001],[406943.050000005,287466.550000005],[406927.799999992,287456.849999994],[406944.399999999,287461.450000001]]]}";
JsonFactory jsonFactory = new JsonFactory();
- JsonParser jsonParser = jsonFactory.createJsonParser(str);
+ JsonParser jsonParser = jsonFactory.createParser(str);
MapGeometry mg = GeometryEngine.jsonToGeometry(jsonParser);
boolean res = GeometryEngine.contains(mg.getGeometry(),
mg.getGeometry(), null);
diff --git a/src/test/java/com/esri/core/geometry/TestConvexHull.java b/src/test/java/com/esri/core/geometry/TestConvexHull.java
new file mode 100644
index 00000000..ee9c764e
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestConvexHull.java
@@ -0,0 +1,1072 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+
+import com.esri.core.geometry.ogc.OGCGeometry;
+
+public class TestConvexHull extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public static void testFewPoints() {
+ {
+ Polygon polygon = new Polygon();
+ polygon.addPath((Point2D[]) null, 0, true);
+ polygon.insertPoint(0, -1, Point2D.construct(5, 5));
+
+ Point convex_hull = (Point) OperatorConvexHull.local().execute(polygon, null);
+ assertTrue(convex_hull.getXY().equals(Point2D.construct(5, 5)));
+ }
+
+ {
+ Point2D[] pts = new Point2D[3];
+
+ pts[0] = Point2D.construct(0, 0);
+ pts[1] = Point2D.construct(0, 0);
+ pts[2] = Point2D.construct(0, 0);
+
+ int[] out_pts = new int[3];
+ int res = ConvexHull.construct(pts, 3, out_pts);
+ assertTrue(res == 1);
+ assertTrue(out_pts[0] == 0);
+ }
+
+ {
+ Point2D[] pts = new Point2D[1];
+ pts[0] = Point2D.construct(0, 0);
+
+ int[] out_pts = new int[1];
+ int res = ConvexHull.construct(pts, 1, out_pts);
+ assertTrue(res == 1);
+ assertTrue(out_pts[0] == 0);
+ }
+ }
+
+ @Test
+ public static void testDegenerate() {
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.DensifyByLength);
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(1, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(2, 0);
+ polygon.lineTo(1, 0);
+ polygon.lineTo(3, 0);
+
+ polygon.startPath(0, 0);
+ polygon.lineTo(1, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(2, 0);
+ polygon.lineTo(1, 0);
+ polygon.lineTo(3, 0);
+
+ Polygon densified = (Polygon) (densify.execute(polygon, .5, null));
+ Polyline convex_hull = (Polyline) (bounding.execute(densified, null));
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.calculateArea2D() == 0.0);
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 3.0 && p2.y == 0.0);
+ }
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(NumberUtils.doubleEps(), 0);
+ polygon.lineTo(0, NumberUtils.doubleEps());
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 5);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(0, 0);
+
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 5);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(0, 0);
+
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(5, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 5);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(0, 0);
+
+ Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+
+ double area = convex_hull.calculateArea2D();
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(area == 100.0);
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 0.0 && p2.y == 10.0);
+ assertTrue(p3.x == 10.0 && p3.y == 10.0);
+ assertTrue(p4.x == 10.0 && p4.y == 0.0);
+ }
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(5, 5);
+ polygon.lineTo(5, 8);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(10, 0);
+
+ Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+
+ double area = convex_hull.calculateArea2D();
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(area == 100.0);
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 0.0 && p2.y == 10.0);
+ assertTrue(p3.x == 10.0 && p3.y == 10.0);
+ assertTrue(p4.x == 10.0 && p4.y == 0.0);
+ }
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(5, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 5);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(0, 0);
+ Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ double area = convex_hull.calculateArea2D();
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(area == 100.0);
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 0.0 && p2.y == 10.0);
+ assertTrue(p3.x == 10.0 && p3.y == 10.0);
+ assertTrue(p4.x == 10.0 && p4.y == 0.0);
+ }
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(0, 0);
+
+ polygon.startPath(0, 10);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 10);
+
+ polygon.startPath(10, 10);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(10, 10);
+
+ polygon.startPath(10, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(10, 0);
+
+ Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ assertTrue(bounding.isConvex(convex_hull, null));
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 0.0 && p2.y == 10.0);
+ assertTrue(p3.x == 10.0 && p3.y == 10.0);
+ assertTrue(p4.x == 10.0 && p4.y == 0.0);
+ }
+
+ {
+ MultiPoint mpoint = new MultiPoint();
+ mpoint.add(4, 4);
+ mpoint.add(4, 4);
+ mpoint.add(4, 4);
+ mpoint.add(4, 4);
+
+ Point convex_hull = (Point) bounding.execute(mpoint, null);
+ assertTrue(convex_hull.calculateArea2D() == 0.0);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.getXY().equals(Point2D.construct(4, 4)));
+ }
+
+ {
+ MultiPoint mpoint = new MultiPoint();
+ mpoint.add(4, 4);
+
+ Point convex_hull = (Point) bounding.execute(mpoint, null);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.getXY().equals(Point2D.construct(4, 4)));
+ }
+
+ {
+ MultiPoint mpoint = new MultiPoint();
+ mpoint.add(4, 4);
+ mpoint.add(4, 5);
+
+ Polyline convex_hull = (Polyline) bounding.execute(mpoint, null);
+ assertTrue(convex_hull.getPointCount() == 2);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.calculateLength2D() == 1.0);
+ }
+
+ {
+ Line line = new Line();
+ line.setStartXY(0, 0);
+ line.setEndXY(0, 1);
+
+ Polyline convex_hull = (Polyline) bounding.execute(line, null);
+ assertTrue(convex_hull.getPointCount() == 2);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.calculateLength2D() == 1.0);
+ }
+
+ {
+ Polyline polyline = new Polyline();
+ polyline.startPath(0, 0);
+ polyline.lineTo(0, 1);
+
+ Polyline convex_hull = (Polyline) bounding.execute(polyline, null);
+ assertTrue(convex_hull.getPointCount() == 2);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(polyline == convex_hull);
+ assertTrue(convex_hull.calculateLength2D() == 1.0);
+ }
+
+ {
+ Envelope env = new Envelope(0, 0, 10, 10);
+ assertTrue(OperatorConvexHull.local().isConvex(env, null));
+
+ Polygon convex_hull = (Polygon) bounding.execute(env, null);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.getPointCount() == 4);
+ assertTrue(convex_hull.getXY(0).equals(Point2D.construct(0, 0)));
+ assertTrue(convex_hull.getXY(1).equals(Point2D.construct(0, 10)));
+ assertTrue(convex_hull.getXY(2).equals(Point2D.construct(10, 10)));
+ assertTrue(convex_hull.getXY(3).equals(Point2D.construct(10, 0)));
+ }
+
+ {
+ Envelope env = new Envelope(0, 0, 0, 10);
+ assertTrue(!OperatorConvexHull.local().isConvex(env, null));
+
+ Polyline convex_hull = (Polyline) bounding.execute(env, null);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.getPointCount() == 2);
+ assertTrue(convex_hull.getXY(0).equals(Point2D.construct(0, 0)));
+ assertTrue(convex_hull.getXY(1).equals(Point2D.construct(0, 10)));
+ }
+
+ {
+ Envelope env = new Envelope(0, 0, 0, 10);
+ assertTrue(!OperatorConvexHull.local().isConvex(env, null));
+
+ Polyline convex_hull = (Polyline) bounding.execute(env, null);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.getPointCount() == 2);
+ assertTrue(convex_hull.getXY(0).equals(Point2D.construct(0, 0)));
+ assertTrue(convex_hull.getXY(1).equals(Point2D.construct(0, 10)));
+ }
+
+ {
+ Envelope env = new Envelope(5, 5, 5, 5);
+ assertTrue(!OperatorConvexHull.local().isConvex(env, null));
+
+ Point convex_hull = (Point) bounding.execute(env, null);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(convex_hull.getXY().equals(Point2D.construct(5, 5)));
+ }
+ }
+
+ @Test
+ public static void testSegment() {
+ {
+ Line line = new Line();
+ line.setStartXY(5, 5);
+ line.setEndXY(5, 5);
+
+ assertTrue(!OperatorConvexHull.local().isConvex(line, null));
+ Point point = (Point) OperatorConvexHull.local().execute(line, null);
+ assertTrue(point.getXY().equals(Point2D.construct(5, 5)));
+ }
+
+ {
+ Line line = new Line();
+ line.setStartXY(5, 5);
+ line.setEndXY(5, 6);
+
+ assertTrue(OperatorConvexHull.local().isConvex(line, null));
+ Polyline polyline = (Polyline) OperatorConvexHull.local().execute(line, null);
+ assertTrue(polyline.getPointCount() == 2);
+ assertTrue(polyline.getXY(0).equals(Point2D.construct(5, 5)));
+ assertTrue(polyline.getXY(1).equals(Point2D.construct(5, 6)));
+ }
+ }
+
+
+ @Test
+ public static void testSquare() {
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.DensifyByLength);
+ OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Difference);
+ OperatorContains contains = (OperatorContains) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Contains);
+
+ Polygon square = new Polygon();
+ square.startPath(0, 0);
+ square.lineTo(2, 3);
+ square.lineTo(1, 4);
+ square.lineTo(0, 5);
+ square.lineTo(0, 7);
+ square.lineTo(2, 7);
+ square.lineTo(0, 10);
+ square.lineTo(4, 7);
+ square.lineTo(6, 7);
+ square.lineTo(7, 10);
+ square.lineTo(8, 10);
+ square.lineTo(10, 10);
+ square.lineTo(8, 7);
+ square.lineTo(10, 5);
+ square.lineTo(8, 3);
+ square.lineTo(10, 1);
+ square.lineTo(10, 0);
+ square.lineTo(5, 5);
+ square.lineTo(8, 0);
+ square.lineTo(4, 3);
+ square.lineTo(5, 0);
+ square.lineTo(3, 1);
+ square.lineTo(3, 0);
+ square.lineTo(2, 1);
+
+ Polygon densified = (Polygon) (densify.execute(square, 1.0, null));
+
+ densified.addAttribute(VertexDescription.Semantics.ID);
+ for (int i = 0; i < densified.getPointCount(); i++)
+ densified.setAttribute(VertexDescription.Semantics.ID, i, 0, i);
+
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ Polygon differenced = (Polygon) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
+
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ @Test
+ public static void testPolygons() {
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.DensifyByLength);
+ OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Difference);
+
+ {
+ Polygon shape = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[1.3734426370715553,-90],[-24.377532184629967,-63.428606327053856],[-25.684686546621553,90],[-24.260574484321914,80.526315789473699],[-25.414389575040037,90],[-23.851448513708718,90],[-23.100135788742072,87.435887853000679],[5.6085096351011448,-48.713222410606306],[1.3734426370715553,-90]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(shape, null));
+ Polygon differenced = (Polygon) (difference.execute(shape, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-179.64843749999693,-43.3535476539993],[-179.99999999999696,-43.430006211999284],[-179.99999999999696,39.329644416999436],[-179.64843749999693,38.98862638799943],[-89.99999999999838,29.008084980999506],[-112.8515624999981,-16.20113770599962],[-115.66406249999804,-18.882554574999688],[-124.80468749999788,-23.7925511709996],[-138.86718749999767,-30.6635901109995],[-157.49999999999736,-38.468358112999354],[-162.42187499999724,-39.56498442199932],[-179.64843749999693,-43.3535476539993]],[[179.99999999999696,-43.430006211999284],[179.64843749999693,-43.50646476999926],[162.0703124999973,-42.36267115399919],[160.3124999999973,-42.24790485699929],[143.78906249999756,-41.1680427339993],[138.16406249999767,-39.64744846799925],[98.43749999999845,-28.523889212999524],[78.39843749999878,-5.1644422999998705],[75.9374999999988,19.738611663999766],[88.2421874999986,33.51651305599954],[108.63281249999815,44.160795160999356],[138.16406249999767,51.02062617799914],[140.9765624999976,51.68129673399923],[160.3124999999973,52.8064856429991],[162.0703124999973,52.908902047999206],[163.12499999999727,52.97036560499911],[165.93749999999716,52.97036560499911],[179.99999999999696,39.329644416999436],[179.99999999999696,-43.430006211999284]]]}").getGeometry());
+ Polygon densified = (Polygon) (densify.execute(polygon, 10.0, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ Polygon differenced = (Polygon) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(1, 0);
+ polygon.lineTo(-1, 0);
+ polygon.lineTo(0, -1);
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-38.554566833914528,21.902000764339238],[-30.516168471666138,90],[-38.554566833914528,21.902000764339238]],[[-43.013227444613932,28.423410187206883],[-43.632473335895916,90],[-42.342268693420237,62.208637129146894],[-37.218731802058755,63.685357222187029],[-32.522681335230686,47.080307818055296],[-40.537308829621097,-21.881392019745604],[-47.59510451722663,18.812521648505964],[-53.25344489340366,30.362745244224911],[-46.629060462410138,90],[-50.069277433245119,18.254168921734287],[-42.171214434397982,72.623347387008081],[-43.000844452530551,90],[-46.162281544954659,90],[-39.462049205071331,90],[-47.434856316742902,38.662565208814371],[-52.13115779642537,-19.952586632199857],[-56.025328966335081,90],[-60.056846215416158,-44.023645282268355],[-60.12338894192289,50.374596189881942],[-35.787508034048379,-7.8839007676038513],[-60.880218074135605,-46.447995750907815],[-67.782542852117956,-85.106300958016107],[-65.053131764313761,-0.96651520578494665],[-72.375821140304154,90],[-78.561502106749245,90],[-83.809168672565946,33.234498214085811],[-60.880218054506344,-46.447995733653201],[-75.637095425108981,59.886574792622838],[-71.364085965028096,31.976373491332097],[-67.89968380886117,90],[-67.544349171474749,8.8435794458927504],[-70.780047377934707,80.683454463576624],[-64.996733940204948,34.349882797035313],[-56.631753638680905,39.815838152456926],[-60.392350183516896,52.75446132093407],[-58.51633728692137,90],[-64.646972065627097,41.444197803942579],[-73.355591244695518,-0.15370205145035776],[-43.013227444613932,28.423410187206883]],[[-69.646471076946,-85.716191379686904],[-62.854465128320491,-45.739046580967972],[-71.377481570643141,-90],[-66.613495837251435,-90],[-66.9765142407159,-90],[-66.870099169607329,-90],[-67.23180828626819,-61.248439074609649],[-58.889775875438851,-90],[-53.391995883729322,-69.476385967096491],[-69.646471076946,-85.716191379686904]]]}").getGeometry());
+ Polygon densified = (Polygon) (densify.execute(polygon, 10.0, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ Polygon differenced = (Polygon) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ // assertTrue(bounding.isConvex(*convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-38.554566833914528,21.902000764339238],[-30.516168471666138,90],[-38.554566833914528,21.902000764339238]],[[-43.013227444613932,28.423410187206883],[-43.632473335895916,90],[-42.342268693420237,62.208637129146894],[-37.218731802058755,63.685357222187029],[-32.522681335230686,47.080307818055296],[-40.537308829621097,-21.881392019745604],[-47.59510451722663,18.812521648505964],[-53.25344489340366,30.362745244224911],[-46.629060462410138,90],[-50.069277433245119,18.254168921734287],[-42.171214434397982,72.623347387008081],[-43.000844452530551,90],[-46.162281544954659,90],[-39.462049205071331,90],[-47.434856316742902,38.662565208814371],[-52.13115779642537,-19.952586632199857],[-56.025328966335081,90],[-60.056846215416158,-44.023645282268355],[-60.12338894192289,50.374596189881942],[-35.787508034048379,-7.8839007676038513],[-60.880218074135605,-46.447995750907815],[-67.782542852117956,-85.106300958016107],[-65.053131764313761,-0.96651520578494665],[-72.375821140304154,90],[-78.561502106749245,90],[-83.809168672565946,33.234498214085811],[-60.880218054506344,-46.447995733653201],[-75.637095425108981,59.886574792622838],[-71.364085965028096,31.976373491332097],[-67.89968380886117,90],[-67.544349171474749,8.8435794458927504],[-70.780047377934707,80.683454463576624],[-64.996733940204948,34.349882797035313],[-56.631753638680905,39.815838152456926],[-60.392350183516896,52.75446132093407],[-58.51633728692137,90],[-64.646972065627097,41.444197803942579],[-73.355591244695518,-0.15370205145035776],[-43.013227444613932,28.423410187206883]],[[-69.646471076946,-85.716191379686904],[-62.854465128320491,-45.739046580967972],[-71.377481570643141,-90],[-66.613495837251435,-90],[-66.9765142407159,-90],[-66.870099169607329,-90],[-67.23180828626819,-61.248439074609649],[-58.889775875438851,-90],[-53.391995883729322,-69.476385967096491],[-69.646471076946,-85.716191379686904]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-36.269498017702901,-26.37490682626369],[-49.146436641060951,-49.881862499696126],[-37.560006446488146,-45.592052597656789],[-39.13770692863632,-69.085816352131204],[-65.415587331361877,-90],[-51.462290812033373,-16.760787566546721],[-28.454456182408332,90],[-36.269498017702901,-26.37490682626369]],[[-40.542178258552283,-90],[-39.13770692863632,-69.085816352131204],[-16.295804332590937,-50.906277575066262],[-40.542178258552283,-90]],[[-16.295804332590937,-50.906277575066262],[-5.6790432913971927,-33.788307256548933],[14.686101893282586,-26.248228042967728],[-16.295804332590937,-50.906277575066262]],[[-37.560006446488146,-45.592052597656789],[-36.269498017702901,-26.37490682626369],[27.479825940672225,90],[71.095881152477034,90],[-5.6790432913971927,-33.788307256548933],[-37.560006446488146,-45.592052597656789]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-77.020281185856106,-80.085419699581706],[-77.328568930885723,-83.404479889897416],[-80.495259564600545,-90],[-77.020281185856106,-80.085419699581706]],[[-77.941187535385211,-90],[-77.328568930885723,-83.404479889897416],[-39.252034383972621,-4.0994329574862469],[-39.29471328421063,-6.5269494453154593],[-77.941187535385211,-90]],[[-77.020281185856106,-80.085419699581706],[-62.688864277996522,74.208210509833052],[-38.108861278327581,80.371071656873013],[-37.597643844595929,90],[-38.663943358642484,29.350366647752089],[-77.020281185856106,-80.085419699581706]],[[-40.265125886194951,-61.722668598742551],[-39.29471328421063,-6.5269494453154593],[-15.554402498931253,44.750073899273843],[-8.4447006412989474,13.127318978368956],[-5.310206313296316,-4.5170390491918795],[-40.265125886194951,-61.722668598742551]],[[-39.252034383972621,-4.0994329574862469],[-38.663943358642484,29.350366647752089],[-22.476078360563164,75.536520897660651],[-15.632105532320049,45.095683888365997],[-39.252034383972621,-4.0994329574862469]],[[-15.554402498931253,44.750073899273843],[-15.632105532320049,45.095683888365997],[-8.9755856576261941,58.959750756602595],[-15.554402498931253,44.750073899273843]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-68.840007952128175,37.060080998089632],[-68.145986924561413,31.114096694815196],[-69.187773850176768,30.693518246958952],[-68.840007952128175,37.060080998089632]],[[-75.780513355389928,-90],[-69.21567111077384,30.182802098042274],[-50.875629803516389,37.146119571446704],[-75.780513355389928,-90]],[[4.2911006174797457,-1.144569312564311],[-66.484019915251849,80.191238371060038],[-65.948228008382316,90],[4.2911006174797457,-1.144569312564311]],[[-90,22.291441435181515],[-69.187773850176768,30.693518246958952],[-69.21567111077384,30.182802098042274],[-90,22.291441435181515]],[[-68.840007952128175,37.060080998089632],[-75.019206401201359,90],[-66.484019915251849,80.191238371060038],[-68.840007952128175,37.060080998089632]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[27.570109889215438,22.850616190228489],[75.703105729477357,-90],[2.1548000876241362,-15.817792950796967],[27.570109889215438,22.850616190228489]],[[-0.069915984436478951,-90],[-46.602410662754053,-89.999999998014729],[-14.977190481820156,-41.883452819243004],[-0.069915984436478951,-90]],[[-14.977190481820156,-41.883452819243004],[-34.509989609682322,21.163004866431177],[2.1548000876241362,-15.817792950796967],[-14.977190481820156,-41.883452819243004]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[28.865673900286581,33.379551302126075],[39.505669183485338,-34.957993133630559],[7.152466542048213,-90],[28.865673900286581,33.379551302126075]],[[-64.597291313620858,2.4515644574812248],[20.050002923927103,90],[24.375150856531356,62.220853377417541],[-64.597291313620858,2.4515644574812248]],[[28.865673900286581,33.379551302126075],[24.375150856531356,62.220853377417541],[35.223952527956932,69.508785974507163],[28.865673900286581,33.379551302126075]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-66.582505384413167,-51.305212522944061],[-60.169897093348865,-90],[-90,-90],[-66.582505384413167,-51.305212522944061]],[[20.858462934004656,-90],[-35.056287147954386,0.78833269359179781],[18.933251883215579,90],[20.858462934004656,-90]],[[-66.582505384413167,-51.305212522944061],[-90,90],[-35.056287147954386,0.78833269359179781],[-66.582505384413167,-51.305212522944061]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[36.692916710279974,-90],[-31.182443792600079,6.434474852744998],[-90,90],[52.245260790065387,57.329280208760991],[36.692916710279974,-90]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-17.959089916602533,-4.3577640799248218],[-29.181784251472308,-90],[-65.493717350127127,15.053615507086979],[-17.959089916602533,-4.3577640799248218]],[[-21.884657435973146,-34.517617672142393],[-17.94005076020704,-4.3655389655558539],[9.3768748358343359,-15.520758655380195],[-21.884657435973146,-34.517617672142393]],[[-17.94005076020704,-4.3655389655558539],[-17.959089916602533,-4.3577640799248218],[-5.8963967801936494,87.694641571893939],[-17.94005076020704,-4.3655389655558539]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[17.198360589495572,-77.168667157542373],[-24.835678541343281,-83.717338556412017],[-30.259244993378722,61.914816728303791],[17.198360589495572,-77.168667157542373]],[[-8.3544985146710644,-90],[17.979891823366039,-79.459092168186686],[21.576625471325329,-90],[-8.3544985146710644,-90]],[[17.979891823366039,-79.459092168186686],[17.198360589495572,-77.168667157542373],[27.846596597209441,-75.509730732825361],[17.979891823366039,-79.459092168186686]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-1.2588613620456419,13.607321860624268],[61.845346679259052,48.415944386573557],[15.226225965240992,-5.3702891526017318],[0.92681706095183469,1.6819284384951441],[3.8469417404317623,-14.250715301799051],[7.2615297628459139,-14.559458820527061],[4.4896578086498238,-17.757471781424698],[14.589138845678622,-72.861774161244625],[-10.508572009494033,-35.06149380752737],[-58.12642296329372,-90],[-15.260062192400673,90],[-1.2588613620456419,13.607321860624268]],[[0.92681706095183469,1.6819284384951441],[-1.2588613620456419,13.607321860624268],[-11.641308877525201,7.8803076458946304],[0.92681706095183469,1.6819284384951441]],[[-10.508572009494033,-35.06149380752737],[4.4896578086498238,-17.757471781424698],[3.8469417404317623,-14.250715301799051],[-26.125369947914503,-11.54064986657559],[-10.508572009494033,-35.06149380752737]],[[39.829571435268129,-17.504227477249202],[7.2615297628459139,-14.559458820527061],[15.226225965240992,-5.3702891526017318],[39.829571435268129,-17.504227477249202]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-19.681975166855118,-34.10344217707847],[-90,89.999999998418275],[53.036316534501381,90],[-19.681975166855118,-34.10344217707847]],[[-52.434509065706855,-90],[-29.2339442498794,-50.405148598356135],[-2.8515119199232331,-90],[-52.434509065706855,-90]],[[18.310881874573923,-90],[-25.473718245381271,-43.987822508814972],[-19.681975166855118,-34.10344217707847],[-15.406194071963924,-41.649717163101563],[18.310881874573923,-90]],[[-29.2339442498794,-50.405148598356135],[-52.27954259799813,-15.81822990020261],[-25.473718245381271,-43.987822508814972],[-29.2339442498794,-50.405148598356135]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[49.939516827702498,-90],[-20.470128740962011,-68.102019032647391],[-20.124197553433845,-67.213968219799824],[34.438329237618149,-61.893901496061034],[49.939516827702498,-90]],[[-82.380918375714089,-73.284249936115529],[-4.7432060543229699,9.1484031048644194],[-11.790524932251525,21.926303986370414],[-3.4862200343039369,10.483021157965428],[19.753975453441285,35.158541777575607],[5.5896897290794696,-1.2030408273476854],[73.839023528563189,-58.052174675157325],[34.438329237618149,-61.893901496061034],[3.6757233436274213,-6.1164440290327313],[-20.124197553433845,-67.213968219799824],[-82.380918375714089,-73.284249936115529]],[[5.5896897290794696,-1.2030408273476854],[4.0842948437219349,0.050896618883412792],[-3.4862200343039369,10.483021157965428],[-4.7432060543229699,9.1484031048644194],[3.6757233436274213,-6.1164440290327313],[5.5896897290794696,-1.2030408273476854]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[4.7618727814345867,-14.245890151885444],[-7.1675180359486266,-90],[-83.232840716292529,40.620187389409224],[-29.219286930421923,6.9418934044755334],[-29.378277853968513,6.9629531745072839],[-28.933835455648254,6.7639099538036529],[4.7618727814345867,-14.245890151885444]],[[51.056303527367277,-43.111190419066219],[4.7618727814345867,-14.245890151885444],[5.632592229367642,-8.716640778187827],[-28.933835455648254,6.7639099538036529],[-29.219286930421923,6.9418934044755334],[2.700964609629902,2.7137705544807242],[12.385960896403816,0.48342578457646468],[51.056303527367277,-43.111190419066219]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-21.426619830983732,-89.379667629404466],[-72.784461583687971,-88.999754827814016],[-81.94289434769162,25.456737039611831],[-38.382426191605546,-57.204127144336077],[-41.663734179022256,-78.439084394036513],[-29.749353943865881,-73.586348060869426],[-21.426619830983732,-89.379667629404466]],[[-21.09971823441461,-90],[-21.426619830983732,-89.379667629404466],[-21.080965849893449,-89.382224558742934],[-21.09971823441461,-90]],[[62.431917153693021,-90],[-21.080965849893449,-89.382224558742934],[-20.486971473666468,-69.813772479288062],[19.166418765782844,-53.662915804391695],[63.671046682728601,-90],[62.431917153693021,-90]],[[-29.749353943865881,-73.586348060869426],[-38.382426191605546,-57.204127144336077],[-31.449272112025476,-12.336278393150847],[-41.028899505665962,-4.5147159296945967],[-30.750049689226596,-7.8112663207986941],[-15.63587330244308,90],[-18.721998818789388,-11.66880646480822],[60.158611185675326,-36.966763960486929],[19.166418765782844,-53.662915804391695],[-19.049573405176112,-22.46036923493498],[-20.486971473666468,-69.813772479288062],[-29.749353943865881,-73.586348060869426]],[[-19.049573405176112,-22.46036923493498],[-18.721998818789388,-11.66880646480822],[-30.750049689226596,-7.8112663207986941],[-31.449272112025476,-12.336278393150847],[-19.049573405176112,-22.46036923493498]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-17.906614911617162,-53.670186894017093],[-72.687715727164573,-90],[-77.889582483879749,90],[-47.149885004784061,16.372797801863811],[-58.874489264131405,8.3403055152440846],[-44.017112148517498,8.8692333739436133],[-43.760297522359615,8.2541153357643502],[-48.398890069305921,4.7201397602360009],[-38.665987052649818,-3.9476907252248874],[-17.906614911617162,-53.670186894017093]],[[-2.7387498969355368,-90],[-17.906614911617162,-53.670186894017093],[-6.8038688963847829,-46.30705103709559],[-2.7387498969355368,-90]],[[-6.8038688963847829,-46.30705103709559],[-8.2224486207861638,-31.0597897622158],[2.1962303277340673,-40.338351652092697],[-6.8038688963847829,-46.30705103709559]],[[-8.2224486207861638,-31.0597897622158],[-38.665987052649818,-3.9476907252248874],[-43.760297522359615,8.2541153357643502],[-42.90074612601282,8.9089763975751382],[-44.017112148517498,8.8692333739436133],[-47.149885004784061,16.372797801863811],[45.190674429223662,79.635046572817728],[40.490070954305672,72.441418146356597],[63.53694979672099,90],[75.056911135062407,13.108310545642606],[-0.027204347469059975,10.435289586728711],[-10.580480746811602,-5.715051428780245],[-8.2224486207861638,-31.0597897622158]],[[-42.90074612601282,8.9089763975751382],[-0.027204347469059975,10.435289586728711],[40.490070954305672,72.441418146356597],[-42.90074612601282,8.9089763975751382]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+ }
+
+ @Test
+ public static void testPolylines() {
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.DensifyByLength);
+ OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Difference);
+ OperatorContains contains = (OperatorContains) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Contains);
+
+ {
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 10);
+ poly.lineTo(0, 20);
+ poly.lineTo(0, 40);
+ poly.lineTo(0, 500);
+
+ Polyline densified = (Polyline) (densify.execute(poly, 10.0, null));
+ Polyline convex_hull = (Polyline) (bounding.execute(densified, null));
+ Polyline differenced = (Polyline) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polyline polyline = new Polyline();
+ polyline.startPath(-200, -90);
+ polyline.lineTo(-180, -85);
+ polyline.lineTo(-90, -70);
+ polyline.lineTo(0, 0);
+ polyline.lineTo(100, 25);
+ polyline.lineTo(170, 45);
+ polyline.lineTo(225, 65);
+
+ Polyline densified = (Polyline) (densify.execute(polyline, 10.0, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ boolean bcontains = contains.execute(convex_hull, densified, SpatialReference.create(4326), null);
+
+ assertTrue(bcontains);
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+ }
+
+ @Test
+ public static void testNonSimpleShape() {
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.DensifyByLength);
+ OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Difference);
+ OperatorContains contains = (OperatorContains) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Contains);
+
+ {
+ Polygon shape = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[6.7260599916745036,-90],[15.304037095218971,-18.924146439950675],[6.3163297788539232,-90],[5.2105387036445823,-59.980719950158637],[5.1217504663506981,-60.571174400735508],[8.2945138368731044,-27.967042187979146],[15.76606600357545,28.594953216378414],[8.4365340991447919,66.880924521951329],[10.115022726199774,65.247385313781265],[12.721206966604395,-23.793016208456883],[12.051875868947576,-11.368909618476637],[11.867118776841318,44.968896646914239],[7.5326099218274614,35.095776924526533],[8.86765609460479,90],[3.2036592678446922,55.507964789691712],[0.23585282258761486,-42.620591380394039],[-1.2660432762142744,90],[5.5580612840503001,-9.4879902323389196],[12.258387597532487,-35.945231749575591],[-48.746716054894101,90],[7.2294405148356846,-15.719232058488402],[13.798313011339591,-10.467172541381753],[7.4430022048746718,6.3951685161785656],[6.4876332898327815,31.10016146737189],[9.3645424359058911,47.123308099298804],[13.398605254542668,-6.4398318586014325],[-90,90],[13.360786277212718,82.971274676174545],[7.9405631778693566,90],[10.512482079680538,90],[16.994982794293946,19.60673041736408],[16.723893839323615,22.728853852102926],[23.178783416627525,90],[6.7260599916745036,-90]],[[26.768777234301993,90],[20.949797955126346,90],[11.967758262201434,-0.45048849056049711],[17.535751576687339,52.767528591651441],[26.768777234301993,90]],[[18.677765775891793,12.559680067559942],[19.060218406331451,90],[17.123595624401705,90],[-2.3805299720687887,-90],[-11.882782057881979,-90],[21.640575461689693,90],[11.368255808198477,85.501555553904794],[17.390084032215348,90],[23.999392897519989,78.255909006554603],[-6.8860811786563101,69.49189433189926],[29.232578855788898,90],[25.951412073846683,90],[-5.5572284181160772,-16.763772082849457],[18.677765775891793,12.559680067559942]]]}").getGeometry());
+ Polygon densified = (Polygon) (densify.execute(shape, 10.0, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ Polygon differenced = (Polygon) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon shape = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-13.630596027421603,3.6796011190640709],[-10.617275202716886,-28.133054337834409],[-81.617315194491695,90],[-4.0763362539824293,-90],[2.8213537979804073,-90],[-5.1515857979973365,-11.605767592612787],[43.477754021411123,35.507543731267589],[-45.818261267516704,-90],[-4.8545715514870018,-64.204371906322223],[-1.744951154293144,-30.257848194381509],[-7.8524748309267149,15.513561279453089],[-10.657563385538953,-81.785061432086309],[-6.3487369893289411,-31.849779201388415],[-14.768278524737962,-12.004393281111058],[-27.001635582579841,90],[-14.967554248940855,-78.970629918591811],[-12.999635147475825,-38.584472796107939],[-13.630596027421603,3.6796011190640709]],[[-16.338143621861352,-37.415690513288375],[-21.553879270366266,-90],[-18.649338100909404,-90],[-24.880584966233631,1.3133858590648728],[-16.483464632078249,-53.979692212288882],[-24.836979215403964,-68.69859399640147],[-29.708282990385214,-90],[-27.469962102507036,-1.6392995673644872],[-20.405051753708271,61.943199597870034],[-18.242567838912599,24.405109362934219],[-66.334547696572528,-52.678390155566603],[-13.471083255903507,-33.782708412943229],[-7.092757068096085,33.673785662500464],[-2.7427100969018205,74.386868339212668],[-8.2174861339989675,90],[-15.699459164009667,90],[-9.5910045204059156,90],[-8.4504603287557369,90],[-1.5498862802092637,2.5144190340747681],[-6.5326327868410639,-17.428029961128306],[-10.947786354404593,31.516236387466538],[-7.4777936485986354,12.486727826508769],[-13.89052186883092,12.397126427870356],[-10.530672679779606,-55.463541447339118],[-8.7161833631330374,-90],[-4.7231067612639519,-90],[-3.9692500849117041,-32.204677519048822],[3.740804266163555,32.88191805391007],[6.2021313886056246,76.617541950091564],[6.1183997672398194,90],[0.59730820015390673,90],[7.3242950674530753,18.030401540676614],[1.8252371571535342,90],[-16.338143621861352,-37.415690513288375]]]}").getGeometry());
+ Polygon densified = (Polygon) (densify.execute(shape, 10.0, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ Polygon differenced = (Polygon) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon shape = (Polygon) (TestCommonMethods.fromJson("{\"rings\":[[[-11.752662474672046,-90],[-76.236530072126513,7.3247326417920817],[18.933251883215579,90],[51.538924439116798,90],[52.253017336758049,80.352482145105284],[41.767201918260639,51.890297432229289],[21.697252770910882,-1.3185641048567049],[45.112193442818935,60.758441021743636],[48.457184967377231,69.626584611257954],[49.531808284502759,70.202152706968036],[52.394797054144334,71.533541126234581],[ 52.9671102343993,70.704964290210626],[58.527850348069251,16.670036266565845],[62.310807912773328,-34.249918700039238],[62.775020703241523,-43.541598916699364],[64.631871865114277,-80.708319783339874],[65.096084655582459,-90],[-11.752662474672046,-90]]]}").getGeometry());
+ Polygon convex_hull = (Polygon) (bounding.execute(shape, null));
+ Polygon differenced = (Polygon) (difference.execute(shape, convex_hull, SpatialReference.create(4326), null));
+ assertTrue(differenced.isEmpty());
+ assertTrue(bounding.isConvex(convex_hull, null));
+ }
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(4, 10);
+ polygon.lineTo(9, 1);
+ polygon.lineTo(1, 1);
+ polygon.lineTo(5, 10);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(10, 0);
+
+ Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+
+ double area = convex_hull.calculateArea2D();
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(area == 100.0);
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 0.0 && p2.y == 10.0);
+ assertTrue(p3.x == 10.0 && p3.y == 10.0);
+ assertTrue(p4.x == 10.0 && p4.y == 0.0);
+ }
+
+ {
+ Polygon polygon = new Polygon();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(8, 10);
+ polygon.lineTo(10, 8);
+ polygon.lineTo(10, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(10, 0);
+
+ // Polygon densified = (Polygon)(densify.execute(polygon, 1, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
+
+ double area = convex_hull.calculateArea2D();
+ assertTrue(bounding.isConvex(convex_hull, null));
+ assertTrue(area == 100.0);
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 0.0 && p2.y == 10.0);
+ assertTrue(p3.x == 10.0 && p3.y == 10.0);
+ assertTrue(p4.x == 10.0 && p4.y == 0.0);
+ }
+ }
+
+ @Test
+ public static void testStar() {
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.DensifyByLength);
+
+ Polygon star = new Polygon();
+ star.startPath(0, 0);
+ star.lineTo(0, 0);
+ star.lineTo(5, 10);
+ star.lineTo(5, 10);
+ star.lineTo(10, 0);
+ star.lineTo(10, 0);
+ star.startPath(0, 5);
+ star.lineTo(0, 5);
+ star.lineTo(10, 5);
+ star.lineTo(10, 5);
+ star.lineTo(5, -5);
+ star.lineTo(5, -5);
+
+ star.reversePath(1);
+
+ Polygon densified = (Polygon) (densify.execute(star, 1.0, null));
+ Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+
+ assertTrue(bounding.isConvex(convex_hull, null));
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ Point2D p5 = convex_hull.getXY(4);
+ Point2D p6 = convex_hull.getXY(5);
+ assertTrue(p1.x == 0.0 && p1.y == 0.0);
+ assertTrue(p2.x == 0.0 && p2.y == 5.0);
+ assertTrue(p3.x == 5.0 && p3.y == 10.0);
+ assertTrue(p4.x == 10.0 && p4.y == 5.0);
+ assertTrue(p5.x == 10.0 && p5.y == 0.0);
+ assertTrue(p6.x == 5.0 && p6.y == -5.0);
+ }
+
+ @Test
+ public static void testPointsArray() {
+ Point2D[] points = new Point2D[6];
+ int[] convex_hull = new int[6];
+
+ for (int i = 0; i < 6; i++)
+ points[i] = new Point2D();
+
+ points[0].x = 0;
+ points[0].y = 0;
+ points[1].x = 5;
+ points[1].y = 10;
+ points[2].x = 10;
+ points[2].y = 0;
+ points[3].x = 0;
+ points[3].y = 5;
+ points[4].x = 10;
+ points[4].y = 5;
+ points[5].x = 5;
+ points[5].y = -5;
+
+ ConvexHull.construct(points, 6, convex_hull);
+ assertTrue(convex_hull[0] == 0);
+ assertTrue(convex_hull[1] == 3);
+ assertTrue(convex_hull[2] == 1);
+ assertTrue(convex_hull[3] == 4);
+ assertTrue(convex_hull[4] == 2);
+ assertTrue(convex_hull[5] == 5);
+ }
+
+ @Test
+ public static void testMergeCursor() {
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+
+ Polygon geom1 = new Polygon();
+ Polygon geom2 = new Polygon();
+ Point geom3 = new Point();
+ Line geom4 = new Line();
+ Envelope geom5 = new Envelope();
+ MultiPoint geom6 = new MultiPoint();
+
+ // polygon
+ geom1.startPath(0, 0);
+ geom1.lineTo(0, 0);
+ geom1.lineTo(5, 11);
+ geom1.lineTo(5, 11);
+ geom1.lineTo(10, 0);
+ geom1.lineTo(10, 0);
+
+ // polygon
+ geom2.startPath(0, 5);
+ geom2.lineTo(0, 5);
+ geom2.lineTo(10, 5);
+ geom2.lineTo(10, 5);
+ geom2.lineTo(5, -5);
+ geom2.lineTo(5, -5);
+
+ // point
+ geom3.setXY(15, 1.25);
+
+ // segment
+ geom4.setEndXY(-5, 1.25);
+ geom4.setStartXY(0, 0);
+
+ // envelope
+ geom5.setCoords(0, 0, 5, 10);
+
+ // multi_point
+ geom6.add(10, 5);
+ geom6.add(10, 10);
+
+ // create cursor
+ Geometry[] geoms = new Geometry[6];
+ geoms[0] = geom1;
+ geoms[1] = geom2;
+ geoms[2] = geom3;
+ geoms[3] = geom4;
+ geoms[4] = geom5;
+ geoms[5] = geom6;
+ GeometryCursor cursor = new SimpleGeometryCursor(geoms);
+
+ // create convex hull from the cursor with b_merge set to true
+ GeometryCursor convex_hull_curs = bounding.execute(cursor, true, null);
+ Polygon convex_hull = (Polygon) (convex_hull_curs.next());
+ assertTrue(convex_hull_curs.next() == null);
+
+ assertTrue(bounding.isConvex(convex_hull, null));
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ Point2D p5 = convex_hull.getXY(4);
+ Point2D p6 = convex_hull.getXY(5);
+ assertTrue(p1.x == 5.0 && p1.y == 11.0);
+ assertTrue(p2.x == 10.0 && p2.y == 10);
+ assertTrue(p3.x == 15.0 && p3.y == 1.25);
+ assertTrue(p4.x == 5.0 && p4.y == -5.0);
+ assertTrue(p5.x == -5.0 && p5.y == 1.25);
+ assertTrue(p6.x == 0.0 && p6.y == 10.0);
+
+ // Test GeometryEngine
+ Geometry[] merged_hull = GeometryEngine.convexHull(geoms, true);
+ convex_hull = (Polygon) merged_hull[0];
+ p1 = convex_hull.getXY(0);
+ p2 = convex_hull.getXY(1);
+ p3 = convex_hull.getXY(2);
+ p4 = convex_hull.getXY(3);
+ p5 = convex_hull.getXY(4);
+ p6 = convex_hull.getXY(5);
+ assertTrue(p1.x == 5.0 && p1.y == 11.0);
+ assertTrue(p2.x == 10.0 && p2.y == 10);
+ assertTrue(p3.x == 15.0 && p3.y == 1.25);
+ assertTrue(p4.x == 5.0 && p4.y == -5.0);
+ assertTrue(p5.x == -5.0 && p5.y == 1.25);
+ assertTrue(p6.x == 0.0 && p6.y == 10.0);
+
+ }
+
+ @Test
+ public void testHullTickTock() {
+ Polygon geom1 = new Polygon();
+ Polygon geom2 = new Polygon();
+ Point geom3 = new Point();
+ Line geom4 = new Line();
+ Envelope geom5 = new Envelope();
+ MultiPoint geom6 = new MultiPoint();
+
+ // polygon
+ geom1.startPath(0, 0);
+ geom1.lineTo(0, 0);
+ geom1.lineTo(5, 11);
+ geom1.lineTo(5, 11);
+ geom1.lineTo(10, 0);
+ geom1.lineTo(10, 0);
+
+ // polygon
+ geom2.startPath(0, 5);
+ geom2.lineTo(0, 5);
+ geom2.lineTo(10, 5);
+ geom2.lineTo(10, 5);
+ geom2.lineTo(5, -5);
+ geom2.lineTo(5, -5);
+
+ // point
+ geom3.setXY(15, 1.25);
+
+ // segment
+ geom4.setEndXY(-5, 1.25);
+ geom4.setStartXY(0, 0);
+
+ // envelope
+ geom5.setCoords(0, 0, 5, 10);
+
+ // multi_point
+ geom6.add(10, 5);
+ geom6.add(10, 10);
+
+ // Create
+ ListeningGeometryCursor gc = new ListeningGeometryCursor();
+ GeometryCursor ticktock = OperatorConvexHull.local().execute(gc, true, null);
+
+ // Use tick-tock to push a geometry and do a piece of work.
+ gc.tick(geom1);
+ ticktock.tock();
+ gc.tick(geom2);
+ ticktock.tock();
+ gc.tick(geom3);// skiped one tock just for testing.
+ ticktock.tock();
+ gc.tick(geom4);
+ ticktock.tock();
+ gc.tick(geom5);
+ ticktock.tock();
+ gc.tick(geom6);
+ ticktock.tock();
+ // Get the result
+ Geometry result = ticktock.next();
+ Polygon convex_hull = (Polygon) result;
+ assertTrue(OperatorConvexHull.local().isConvex(convex_hull, null));
+
+ Point2D p1 = convex_hull.getXY(0);
+ Point2D p2 = convex_hull.getXY(1);
+ Point2D p3 = convex_hull.getXY(2);
+ Point2D p4 = convex_hull.getXY(3);
+ Point2D p5 = convex_hull.getXY(4);
+ Point2D p6 = convex_hull.getXY(5);
+ assertTrue(p1.x == 5.0 && p1.y == 11.0);
+ assertTrue(p2.x == 10.0 && p2.y == 10);
+ assertTrue(p3.x == 15.0 && p3.y == 1.25);
+ assertTrue(p4.x == 5.0 && p4.y == -5.0);
+ assertTrue(p5.x == -5.0 && p5.y == 1.25);
+ assertTrue(p6.x == 0.0 && p6.y == 10.0);
+ }
+
+ @Test
+ public void testHullIssueGithub172() {
+ {
+ //empty
+ OGCGeometry geom = OGCGeometry.fromText("MULTIPOINT EMPTY");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("POINT EMPTY") == 0);
+ }
+ {
+ //Point
+ OGCGeometry geom = OGCGeometry.fromText("POINT (1 2)");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("POINT (1 2)") == 0);
+ }
+ {
+ //line
+ OGCGeometry geom = OGCGeometry.fromText("MULTIPOINT (1 1, 2 2)");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("LINESTRING (1 1, 2 2)") == 0);
+ }
+ {
+ //empty
+ OGCGeometry geom = OGCGeometry.fromText("GEOMETRYCOLLECTION EMPTY");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("POINT EMPTY") == 0);
+ }
+
+ {
+ //empty
+ OGCGeometry geom = OGCGeometry.fromText("GEOMETRYCOLLECTION (POINT (1 2))");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("POINT (1 2)") == 0);
+ }
+
+ {
+ //empty
+ OGCGeometry geom = OGCGeometry.fromText("GEOMETRYCOLLECTION(POLYGON EMPTY, POINT(1 1), LINESTRING EMPTY, MULTIPOLYGON EMPTY, MULTILINESTRING EMPTY)");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("POINT (1 1)") == 0);
+ }
+
+ {
+ //empty
+ OGCGeometry geom = OGCGeometry.fromText("GEOMETRYCOLLECTION(POLYGON EMPTY, LINESTRING (1 1, 2 2), POINT(3 3), LINESTRING EMPTY, MULTIPOLYGON EMPTY, MULTILINESTRING EMPTY)");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("LINESTRING (1 1, 3 3)") == 0);
+ }
+
+ {
+ //empty
+ OGCGeometry geom = OGCGeometry.fromText("GEOMETRYCOLLECTION(POLYGON EMPTY, LINESTRING (1 1, 2 2), POINT(3 3), LINESTRING EMPTY, POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5)))");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("POLYGON ((-10 -10, 10 -10, 10 10, -10 10, -10 -10))") == 0);
+ }
+ }
+
+ @Test
+ public void testHullIssueGithub194() {
+ {
+ //empty
+ OGCGeometry geom = OGCGeometry.fromText("GEOMETRYCOLLECTION(POLYGON EMPTY, POLYGON((0 0, 1 0, 1 1, 0 0)), POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5)))");
+ OGCGeometry result = geom.convexHull();
+ String text = result.asText();
+ assertTrue(text.compareTo("POLYGON ((-10 -10, 10 -10, 10 10, -10 10, -10 -10))") == 0);
+ }
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestCut.java b/src/test/java/com/esri/core/geometry/TestCut.java
similarity index 82%
rename from unittest/com/esri/core/geometry/TestCut.java
rename to src/test/java/com/esri/core/geometry/TestCut.java
index f67a4d1f..a388ff01 100644
--- a/unittest/com/esri/core/geometry/TestCut.java
+++ b/src/test/java/com/esri/core/geometry/TestCut.java
@@ -1,520 +1,560 @@
-package com.esri.core.geometry;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestCut extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public static void testCut4326() {
- SpatialReference sr = SpatialReference.create(4326);
- testConsiderTouch1(sr);
- testConsiderTouch2(sr);
- testPolygon5(sr);
- testPolygon7(sr);
- testPolygon8(sr);
- testPolygon9(sr);
- testEngine(sr);
-
- }
-
- public static void testConsiderTouch1(SpatialReference spatialReference) {
- OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
- OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
-
- Polyline polyline1 = makePolyline1();
- Polyline cutter1 = makePolylineCutter1();
-
- GeometryCursor cursor = opCut.execute(true, polyline1, cutter1,
- spatialReference, null);
- Polyline cut;
- int pathCount;
- int segmentCount;
- double length;
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 4);
- assertTrue(segmentCount == 4);
- assertTrue(length == 6);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 6);
- assertTrue(segmentCount == 8);
- assertTrue(length == 12);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 1);
- assertTrue(segmentCount == 1);
- assertTrue(length == 1);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 1);
- assertTrue(segmentCount == 1);
- assertTrue(length == 1);
-
- cut = (Polyline) cursor.next();
- assertTrue(cut == null);
- }
-
- public static void testConsiderTouch2(SpatialReference spatialReference) {
- OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
- OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
-
- Polyline polyline2 = makePolyline2();
- Polyline cutter2 = makePolylineCutter2();
-
- GeometryCursor cursor = opCut.execute(true, polyline2, cutter2,
- spatialReference, null);
- Polyline cut;
- int pathCount;
- int segmentCount;
- double length;
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 4);
- assertTrue(segmentCount == 4);
- assertTrue(Math.abs(length - 5.74264068) <= 0.001);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 6);
- assertTrue(segmentCount == 8);
- assertTrue(length == 6.75);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 1);
- assertTrue(segmentCount == 1);
- assertTrue(Math.abs(length - 0.5) <= 0.001);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 1);
- assertTrue(segmentCount == 1);
- assertTrue(Math.abs(length - 0.25) <= 0.001);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 1);
- assertTrue(segmentCount == 1);
- assertTrue(Math.abs(length - 1) <= 0.001);
-
- cut = (Polyline) cursor.next();
- pathCount = cut.getPathCount();
- segmentCount = cut.getSegmentCount();
- length = cut.calculateLength2D();
- assertTrue(pathCount == 1);
- assertTrue(segmentCount == 1);
- assertTrue(Math.abs(length - 1.41421356) <= 0.001);
-
- cut = (Polyline) cursor.next();
- assertTrue(cut == null);
- }
-
- public static void testPolygon5(SpatialReference spatialReference) {
- OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
- OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
-
- Polygon polygon5 = makePolygon5();
- Polyline cutter5 = makePolygonCutter5();
-
- GeometryCursor cursor = opCut.execute(true, polygon5, cutter5,
- spatialReference, null);
- Polygon cut;
- int pathCount;
- int pointCount;
- double area;
-
- cut = (Polygon) cursor.next();
- pathCount = cut.getPathCount();
- pointCount = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(pathCount == 4);
- assertTrue(pointCount == 12);
- assertTrue(area == 450);
-
- cut = (Polygon) cursor.next();
- pathCount = cut.getPathCount();
- pointCount = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(pathCount == 1);
- assertTrue(pointCount == 4);
- assertTrue(area == 450);
-
- cut = (Polygon) cursor.next();
- assertTrue(cut == null);
- }
-
- public static void testPolygon7(SpatialReference spatialReference) {
- OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
- OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
-
- Polygon cut;
- int path_count;
- int point_count;
- double area;
-
- Polygon polygon7 = makePolygon7();
- Polyline cutter7 = makePolygonCutter7();
- GeometryCursor cursor = opCut.execute(false, polygon7, cutter7,
- spatialReference, null);
-
- cut = (Polygon) cursor.next();
- path_count = cut.getPathCount();
- point_count = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(path_count == 1);
- assertTrue(point_count == 4);
- assertTrue(area == 100);
-
- cut = (Polygon) cursor.next();
- assertTrue(cut.isEmpty());
-
- cut = (Polygon) cursor.next();
- path_count = cut.getPathCount();
- point_count = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(path_count == 2);
- assertTrue(point_count == 8);
- assertTrue(area == 800);
-
- cut = (Polygon) cursor.next();
- assertTrue(cut == null);
- }
-
- public static void testPolygon8(SpatialReference spatialReference) {
- OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
- OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
-
- Polygon polygon8 = makePolygon8();
- Polyline cutter8 = makePolygonCutter8();
-
- GeometryCursor cursor = opCut.execute(true, polygon8, cutter8,
- spatialReference, null);
- Polygon cut;
- int pathCount;
- int pointCount;
- double area;
-
- cut = (Polygon) cursor.next();
- assertTrue(cut.isEmpty());
-
- cut = (Polygon) cursor.next();
- pathCount = cut.getPathCount();
- pointCount = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(pathCount == 1);
- assertTrue(pointCount == 4);
- assertTrue(area == 100);
-
- cut = (Polygon) cursor.next();
- pathCount = cut.getPathCount();
- pointCount = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(pathCount == 2);
- assertTrue(pointCount == 8);
- assertTrue(area == 800);
-
- cut = (Polygon) cursor.next();
- assertTrue(cut == null);
- }
-
- public static void testPolygon9(SpatialReference spatialReference) {
- OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
- OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
-
- Polygon cut;
- int path_count;
- int point_count;
- double area;
-
- Polygon polygon9 = makePolygon9();
- Polyline cutter9 = makePolygonCutter9();
- GeometryCursor cursor = opCut.execute(false, polygon9, cutter9,
- spatialReference, null);
-
- cut = (Polygon) cursor.next();
- path_count = cut.getPathCount();
- point_count = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(path_count == 3);
- assertTrue(point_count == 12);
- assertTrue(area == 150);
-
- cut = (Polygon) cursor.next();
- path_count = cut.getPathCount();
- point_count = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(path_count == 3);
- assertTrue(point_count == 12);
- assertTrue(area == 150);
-
- cut = (Polygon) cursor.next();
- assertTrue(cut == null);
- }
-
- public static void testEngine(SpatialReference spatialReference) {
- Polygon polygon8 = makePolygon8();
- Polyline cutter8 = makePolygonCutter8();
-
- Geometry[] cuts = GeometryEngine.cut(polygon8, cutter8,
- spatialReference);
- Polygon cut;
- int pathCount;
- int pointCount;
- double area;
-
- cut = (Polygon) cuts[0];
- pathCount = cut.getPathCount();
- pointCount = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(pathCount == 1);
- assertTrue(pointCount == 4);
- assertTrue(area == 100);
-
- cut = (Polygon) cuts[1];
- pathCount = cut.getPathCount();
- pointCount = cut.getPointCount();
- area = cut.calculateArea2D();
- assertTrue(pathCount == 2);
- assertTrue(pointCount == 8);
- assertTrue(area == 800);
- }
-
- public static Polyline makePolyline1() {
- Polyline poly = new Polyline();
-
- poly.startPath(0, 0);
- poly.lineTo(2, 0);
- poly.lineTo(4, 0);
- poly.lineTo(6, 0);
- poly.lineTo(8, 0);
- poly.lineTo(10, 0);
- poly.lineTo(12, 0);
- poly.lineTo(14, 0);
- poly.lineTo(16, 0);
- poly.lineTo(18, 0);
- poly.lineTo(20, 0);
-
- return poly;
- }
-
- public static Polyline makePolylineCutter1() {
- Polyline poly = new Polyline();
-
- poly.startPath(1, 0);
- poly.lineTo(4, 0);
-
- poly.startPath(6, -1);
- poly.lineTo(6, 1);
-
- poly.startPath(6, 0);
- poly.lineTo(8, 0);
-
- poly.startPath(9, -1);
- poly.lineTo(9, 1);
-
- poly.startPath(10, 0);
- poly.lineTo(12, 0);
-
- poly.startPath(12, 1);
- poly.lineTo(12, -1);
-
- poly.startPath(12, 0);
- poly.lineTo(15, 0);
-
- poly.startPath(15, 1);
- poly.lineTo(15, -1);
-
- poly.startPath(16, 0);
- poly.lineTo(16, -1);
- poly.lineTo(17, -1);
- poly.lineTo(17, 1);
- poly.lineTo(17, 0);
- poly.lineTo(18, 0);
-
- poly.startPath(18, 0);
- poly.lineTo(18, -1);
-
- return poly;
- }
-
- public static Polyline makePolyline2() {
- Polyline poly = new Polyline();
-
- poly.startPath(-2, 0);
- poly.lineTo(-1, 0);
- poly.lineTo(0, 0);
- poly.lineTo(2, 0);
- poly.lineTo(4, 2);
- poly.lineTo(8, 2);
- poly.lineTo(10, 4);
- poly.lineTo(12, 4);
-
- return poly;
- }
-
- public static Polyline makePolylineCutter2() {
- Polyline poly = new Polyline();
-
- poly.startPath(-1.5, 0);
- poly.lineTo(-.75, 0);
-
- poly.startPath(-.5, 0);
- poly.lineTo(1, 0);
- poly.lineTo(1, 2);
- poly.lineTo(3, -2);
- poly.lineTo(4, 2);
- poly.lineTo(5, -2);
- poly.lineTo(5, 4);
- poly.lineTo(8, 2);
- poly.lineTo(6, 0);
- poly.lineTo(6, 3);
-
- poly.startPath(9, 5);
- poly.lineTo(9, 2);
- poly.lineTo(10, 2);
- poly.lineTo(10, 5);
- poly.lineTo(10.5, 5);
- poly.lineTo(10.5, 3);
-
- poly.startPath(11, 4);
- poly.lineTo(11, 5);
-
- poly.startPath(12, 5);
- poly.lineTo(12, 4);
-
- return poly;
- }
-
- public static Polygon makePolygon5() {
- Polygon poly = new Polygon();
-
- poly.startPath(0, 0);
- poly.lineTo(0, 30);
- poly.lineTo(30, 30);
- poly.lineTo(30, 0);
-
- return poly;
- }
-
- public static Polyline makePolygonCutter5() {
- Polyline poly = new Polyline();
-
- poly.startPath(15, 0);
- poly.lineTo(0, 15);
- poly.lineTo(15, 30);
- poly.lineTo(30, 15);
- poly.lineTo(15, 0);
-
- return poly;
- }
-
- public static Polygon makePolygon7() {
- Polygon poly = new Polygon();
-
- poly.startPath(0, 0);
- poly.lineTo(0, 30);
- poly.lineTo(30, 30);
- poly.lineTo(30, 0);
-
- return poly;
- }
-
- public static Polyline makePolygonCutter7() {
- Polyline poly = new Polyline();
-
- poly.startPath(10, 10);
- poly.lineTo(20, 10);
- poly.lineTo(20, 20);
- poly.lineTo(10, 20);
- poly.lineTo(10, 10);
-
- return poly;
- }
-
- public static Polygon makePolygon8() {
- Polygon poly = new Polygon();
-
- poly.startPath(0, 0);
- poly.lineTo(0, 30);
- poly.lineTo(30, 30);
- poly.lineTo(30, 0);
-
- return poly;
- }
-
- public static Polyline makePolygonCutter8() {
- Polyline poly = new Polyline();
-
- poly.startPath(10, 10);
- poly.lineTo(10, 20);
- poly.lineTo(20, 20);
- poly.lineTo(20, 10);
- poly.lineTo(10, 10);
-
- return poly;
- }
-
- public static Polygon makePolygon9() {
- Polygon poly = new Polygon();
-
- poly.startPath(0, 0);
- poly.lineTo(0, 10);
- poly.lineTo(10, 10);
- poly.lineTo(10, 0);
-
- poly.startPath(0, 20);
- poly.lineTo(0, 30);
- poly.lineTo(10, 30);
- poly.lineTo(10, 20);
-
- poly.startPath(0, 40);
- poly.lineTo(0, 50);
- poly.lineTo(10, 50);
- poly.lineTo(10, 40);
-
- return poly;
- }
-
- public static Polyline makePolygonCutter9() {
- Polyline poly = new Polyline();
-
- poly.startPath(5, -1);
- poly.lineTo(5, 51);
-
- return poly;
- }
-}
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class TestCut extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public static void testCut4326() {
+ SpatialReference sr = SpatialReference.create(4326);
+ testConsiderTouch1(sr);
+ testConsiderTouch2(sr);
+ testPolygon5(sr);
+ testPolygon7(sr);
+ testPolygon8(sr);
+ testPolygon9(sr);
+ testEngine(sr);
+
+ }
+
+ private static void testConsiderTouch1(SpatialReference spatialReference) {
+ OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
+ OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
+
+ Polyline polyline1 = makePolyline1();
+ Polyline cutter1 = makePolylineCutter1();
+
+ GeometryCursor cursor = opCut.execute(true, polyline1, cutter1,
+ spatialReference, null);
+ Polyline cut;
+ int pathCount;
+ int segmentCount;
+ double length;
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 4);
+ assertTrue(segmentCount == 4);
+ assertTrue(length == 6);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 6);
+ assertTrue(segmentCount == 8);
+ assertTrue(length == 12);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 1);
+ assertTrue(segmentCount == 1);
+ assertTrue(length == 1);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 1);
+ assertTrue(segmentCount == 1);
+ assertTrue(length == 1);
+
+ cut = (Polyline) cursor.next();
+ assertTrue(cut == null);
+ }
+
+ private static void testConsiderTouch2(SpatialReference spatialReference) {
+ OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
+ OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
+
+ Polyline polyline2 = makePolyline2();
+ Polyline cutter2 = makePolylineCutter2();
+
+ GeometryCursor cursor = opCut.execute(true, polyline2, cutter2,
+ spatialReference, null);
+ Polyline cut;
+ int pathCount;
+ int segmentCount;
+ double length;
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 4);
+ assertTrue(segmentCount == 4);
+ assertTrue(Math.abs(length - 5.74264068) <= 0.001);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 6);
+ assertTrue(segmentCount == 8);
+ assertTrue(length == 6.75);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 1);
+ assertTrue(segmentCount == 1);
+ assertTrue(Math.abs(length - 0.5) <= 0.001);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 1);
+ assertTrue(segmentCount == 1);
+ assertTrue(Math.abs(length - 0.25) <= 0.001);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 1);
+ assertTrue(segmentCount == 1);
+ assertTrue(Math.abs(length - 1) <= 0.001);
+
+ cut = (Polyline) cursor.next();
+ pathCount = cut.getPathCount();
+ segmentCount = cut.getSegmentCount();
+ length = cut.calculateLength2D();
+ assertTrue(pathCount == 1);
+ assertTrue(segmentCount == 1);
+ assertTrue(Math.abs(length - 1.41421356) <= 0.001);
+
+ cut = (Polyline) cursor.next();
+ assertTrue(cut == null);
+ }
+
+ private static void testPolygon5(SpatialReference spatialReference) {
+ OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
+ OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
+
+ Polygon polygon5 = makePolygon5();
+ Polyline cutter5 = makePolygonCutter5();
+
+ GeometryCursor cursor = opCut.execute(true, polygon5, cutter5,
+ spatialReference, null);
+ Polygon cut;
+ int pathCount;
+ int pointCount;
+ double area;
+
+ cut = (Polygon) cursor.next();
+ pathCount = cut.getPathCount();
+ pointCount = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(pathCount == 4);
+ assertTrue(pointCount == 12);
+ assertTrue(area == 450);
+
+ cut = (Polygon) cursor.next();
+ pathCount = cut.getPathCount();
+ pointCount = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(pathCount == 1);
+ assertTrue(pointCount == 4);
+ assertTrue(area == 450);
+
+ cut = (Polygon) cursor.next();
+ assertTrue(cut == null);
+ }
+
+ private static void testPolygon7(SpatialReference spatialReference) {
+ OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
+ OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
+
+ Polygon cut;
+ int path_count;
+ int point_count;
+ double area;
+
+ Polygon polygon7 = makePolygon7();
+ Polyline cutter7 = makePolygonCutter7();
+ GeometryCursor cursor = opCut.execute(false, polygon7, cutter7,
+ spatialReference, null);
+
+ cut = (Polygon) cursor.next();
+ path_count = cut.getPathCount();
+ point_count = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(path_count == 1);
+ assertTrue(point_count == 4);
+ assertTrue(area == 100);
+
+ cut = (Polygon) cursor.next();
+ assertTrue(cut.isEmpty());
+
+ cut = (Polygon) cursor.next();
+ path_count = cut.getPathCount();
+ point_count = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(path_count == 2);
+ assertTrue(point_count == 8);
+ assertTrue(area == 800);
+
+ cut = (Polygon) cursor.next();
+ assertTrue(cut == null);
+ }
+
+ private static void testPolygon8(SpatialReference spatialReference) {
+ OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
+ OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
+
+ Polygon polygon8 = makePolygon8();
+ Polyline cutter8 = makePolygonCutter8();
+
+ GeometryCursor cursor = opCut.execute(true, polygon8, cutter8,
+ spatialReference, null);
+ Polygon cut;
+ int pathCount;
+ int pointCount;
+ double area;
+
+ cut = (Polygon) cursor.next();
+ assertTrue(cut.isEmpty());
+
+ cut = (Polygon) cursor.next();
+ pathCount = cut.getPathCount();
+ pointCount = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(pathCount == 1);
+ assertTrue(pointCount == 4);
+ assertTrue(area == 100);
+
+ cut = (Polygon) cursor.next();
+ pathCount = cut.getPathCount();
+ pointCount = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(pathCount == 2);
+ assertTrue(pointCount == 8);
+ assertTrue(area == 800);
+
+ cut = (Polygon) cursor.next();
+ assertTrue(cut == null);
+ }
+
+ private static void testPolygon9(SpatialReference spatialReference) {
+ OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
+ OperatorCut opCut = (OperatorCut) engine.getOperator(Operator.Type.Cut);
+
+ Polygon cut;
+ int path_count;
+ int point_count;
+ double area;
+
+ Polygon polygon9 = makePolygon9();
+ Polyline cutter9 = makePolygonCutter9();
+ GeometryCursor cursor = opCut.execute(false, polygon9, cutter9,
+ spatialReference, null);
+
+ cut = (Polygon) cursor.next();
+ path_count = cut.getPathCount();
+ point_count = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(path_count == 3);
+ assertTrue(point_count == 12);
+ assertTrue(area == 150);
+
+ cut = (Polygon) cursor.next();
+ path_count = cut.getPathCount();
+ point_count = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(path_count == 3);
+ assertTrue(point_count == 12);
+ assertTrue(area == 150);
+
+ cut = (Polygon) cursor.next();
+ assertTrue(cut == null);
+ }
+
+ private static void testEngine(SpatialReference spatialReference) {
+ Polygon polygon8 = makePolygon8();
+ Polyline cutter8 = makePolygonCutter8();
+
+ Geometry[] cuts = GeometryEngine.cut(polygon8, cutter8,
+ spatialReference);
+ Polygon cut;
+ int pathCount;
+ int pointCount;
+ double area;
+
+ cut = (Polygon) cuts[0];
+ pathCount = cut.getPathCount();
+ pointCount = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(pathCount == 1);
+ assertTrue(pointCount == 4);
+ assertTrue(area == 100);
+
+ cut = (Polygon) cuts[1];
+ pathCount = cut.getPathCount();
+ pointCount = cut.getPointCount();
+ area = cut.calculateArea2D();
+ assertTrue(pathCount == 2);
+ assertTrue(pointCount == 8);
+ assertTrue(area == 800);
+ }
+
+ private static Polyline makePolyline1() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(0, 0);
+ poly.lineTo(2, 0);
+ poly.lineTo(4, 0);
+ poly.lineTo(6, 0);
+ poly.lineTo(8, 0);
+ poly.lineTo(10, 0);
+ poly.lineTo(12, 0);
+ poly.lineTo(14, 0);
+ poly.lineTo(16, 0);
+ poly.lineTo(18, 0);
+ poly.lineTo(20, 0);
+
+ return poly;
+ }
+
+ private static Polyline makePolylineCutter1() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(1, 0);
+ poly.lineTo(4, 0);
+
+ poly.startPath(6, -1);
+ poly.lineTo(6, 1);
+
+ poly.startPath(6, 0);
+ poly.lineTo(8, 0);
+
+ poly.startPath(9, -1);
+ poly.lineTo(9, 1);
+
+ poly.startPath(10, 0);
+ poly.lineTo(12, 0);
+
+ poly.startPath(12, 1);
+ poly.lineTo(12, -1);
+
+ poly.startPath(12, 0);
+ poly.lineTo(15, 0);
+
+ poly.startPath(15, 1);
+ poly.lineTo(15, -1);
+
+ poly.startPath(16, 0);
+ poly.lineTo(16, -1);
+ poly.lineTo(17, -1);
+ poly.lineTo(17, 1);
+ poly.lineTo(17, 0);
+ poly.lineTo(18, 0);
+
+ poly.startPath(18, 0);
+ poly.lineTo(18, -1);
+
+ return poly;
+ }
+
+ private static Polyline makePolyline2() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(-2, 0);
+ poly.lineTo(-1, 0);
+ poly.lineTo(0, 0);
+ poly.lineTo(2, 0);
+ poly.lineTo(4, 2);
+ poly.lineTo(8, 2);
+ poly.lineTo(10, 4);
+ poly.lineTo(12, 4);
+
+ return poly;
+ }
+
+ private static Polyline makePolylineCutter2() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(-1.5, 0);
+ poly.lineTo(-.75, 0);
+
+ poly.startPath(-.5, 0);
+ poly.lineTo(1, 0);
+ poly.lineTo(1, 2);
+ poly.lineTo(3, -2);
+ poly.lineTo(4, 2);
+ poly.lineTo(5, -2);
+ poly.lineTo(5, 4);
+ poly.lineTo(8, 2);
+ poly.lineTo(6, 0);
+ poly.lineTo(6, 3);
+
+ poly.startPath(9, 5);
+ poly.lineTo(9, 2);
+ poly.lineTo(10, 2);
+ poly.lineTo(10, 5);
+ poly.lineTo(10.5, 5);
+ poly.lineTo(10.5, 3);
+
+ poly.startPath(11, 4);
+ poly.lineTo(11, 5);
+
+ poly.startPath(12, 5);
+ poly.lineTo(12, 4);
+
+ return poly;
+ }
+
+ private static Polygon makePolygon5() {
+ Polygon poly = new Polygon();
+
+ poly.startPath(0, 0);
+ poly.lineTo(0, 30);
+ poly.lineTo(30, 30);
+ poly.lineTo(30, 0);
+
+ return poly;
+ }
+
+ private static Polyline makePolygonCutter5() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(15, 0);
+ poly.lineTo(0, 15);
+ poly.lineTo(15, 30);
+ poly.lineTo(30, 15);
+ poly.lineTo(15, 0);
+
+ return poly;
+ }
+
+ private static Polygon makePolygon7() {
+ Polygon poly = new Polygon();
+
+ poly.startPath(0, 0);
+ poly.lineTo(0, 30);
+ poly.lineTo(30, 30);
+ poly.lineTo(30, 0);
+
+ return poly;
+ }
+
+ private static Polyline makePolygonCutter7() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(10, 10);
+ poly.lineTo(20, 10);
+ poly.lineTo(20, 20);
+ poly.lineTo(10, 20);
+ poly.lineTo(10, 10);
+
+ return poly;
+ }
+
+ private static Polygon makePolygon8() {
+ Polygon poly = new Polygon();
+
+ poly.startPath(0, 0);
+ poly.lineTo(0, 30);
+ poly.lineTo(30, 30);
+ poly.lineTo(30, 0);
+
+ return poly;
+ }
+
+ private static Polyline makePolygonCutter8() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(10, 10);
+ poly.lineTo(10, 20);
+ poly.lineTo(20, 20);
+ poly.lineTo(20, 10);
+ poly.lineTo(10, 10);
+
+ return poly;
+ }
+
+ private static Polygon makePolygon9() {
+ Polygon poly = new Polygon();
+
+ poly.startPath(0, 0);
+ poly.lineTo(0, 10);
+ poly.lineTo(10, 10);
+ poly.lineTo(10, 0);
+
+ poly.startPath(0, 20);
+ poly.lineTo(0, 30);
+ poly.lineTo(10, 30);
+ poly.lineTo(10, 20);
+
+ poly.startPath(0, 40);
+ poly.lineTo(0, 50);
+ poly.lineTo(10, 50);
+ poly.lineTo(10, 40);
+
+ return poly;
+ }
+
+ private static Polyline makePolygonCutter9() {
+ Polyline poly = new Polyline();
+
+ poly.startPath(5, -1);
+ poly.lineTo(5, 51);
+
+ return poly;
+ }
+
+ @Test
+ public void testGithubIssue253() {
+ //https://github.com/Esri/geometry-api-java/issues/253
+ SpatialReference spatialReference = SpatialReference.create(3857);
+ Polyline poly1 = new Polyline();
+ poly1.startPath(610, 552);
+ poly1.lineTo(610, 552);
+ Polyline poly2 = new Polyline();
+ poly2.startPath(610, 552);
+ poly2.lineTo(610, 552);
+ GeometryCursor cursor = OperatorCut.local().execute(true, poly1, poly2, spatialReference, null);
+
+ Geometry res = cursor.next();
+ assertTrue(res == null);
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestDifference.java b/src/test/java/com/esri/core/geometry/TestDifference.java
similarity index 93%
rename from unittest/com/esri/core/geometry/TestDifference.java
rename to src/test/java/com/esri/core/geometry/TestDifference.java
index ca7bc3d4..2ea73ffc 100644
--- a/unittest/com/esri/core/geometry/TestDifference.java
+++ b/src/test/java/com/esri/core/geometry/TestDifference.java
@@ -1,6 +1,32 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
+
import junit.framework.TestCase;
+
import org.junit.Test;
public class TestDifference extends TestCase {
@@ -476,6 +502,14 @@ public static void testDifferenceOnPolyline() {
assertEquals(5, pointCountDiffPolyline);
}
+
+ @Test
+ public static void testDifferencePolylineAlongPolygonBoundary() {
+ Polyline polyline = (Polyline)GeometryEngine.geometryFromWkt("LINESTRING(0 0, 0 5, -2 5)", 0, Geometry.Type.Unknown);
+ Polygon polygon = (Polygon)GeometryEngine.geometryFromWkt("POLYGON((0 0, 5 0, 5 5, 0 5, 0 0))", 0, Geometry.Type.Unknown);
+ Geometry result = OperatorDifference.local().execute(polyline, polygon, null, null);
+ assertEquals(GeometryEngine.geometryToJson(null, result), "{\"paths\":[[[0,5],[-2,5]]]}");
+ }
public static Polygon makePolygon1() {
Polygon poly = new Polygon();
diff --git a/unittest/com/esri/core/geometry/TestDistance.java b/src/test/java/com/esri/core/geometry/TestDistance.java
similarity index 75%
rename from unittest/com/esri/core/geometry/TestDistance.java
rename to src/test/java/com/esri/core/geometry/TestDistance.java
index 9fc159d2..50399967 100644
--- a/unittest/com/esri/core/geometry/TestDistance.java
+++ b/src/test/java/com/esri/core/geometry/TestDistance.java
@@ -1,10 +1,30 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
-import java.io.IOException;
import junit.framework.TestCase;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
import org.junit.Test;
public class TestDistance extends TestCase {
@@ -62,6 +82,14 @@ public static void testDistanceBetweenTriangles() {
assertTrue(0.0 < distance && distance < xSeparation + ySeparation);
}
+ @Test
+ public static void testDistanceBetweenPointAndEnvelope() {
+ Envelope env = new Envelope(23,23, 23,23);
+ Point pt = new Point(30, 30);
+ double dist = GeometryEngine.distance(env, pt, null); // expect just under 10.
+ assertTrue(Math.abs(dist - 9.8994949) < 0.0001);
+ }
+
@Test
public static void testDistanceBetweenHugeGeometries() {
/* const */int N = 1000; // Should be even
@@ -138,17 +166,13 @@ private static Point makePoint() {
}
@Test
- public static void testDistanceWithNullSpatialReference()
- throws JsonParseException, IOException {
+ public static void testDistanceWithNullSpatialReference() {
// There was a bug that distance op did not work with null Spatial
// Reference.
String str1 = "{\"paths\":[[[-117.138791850991,34.017492675023],[-117.138762336971,34.0174925550462]]]}";
String str2 = "{\"paths\":[[[-117.138867827972,34.0174854109623],[-117.138850197027,34.0174929160126],[-117.138791850991,34.017492675023]]]}";
- JsonFactory jsonFactory = new JsonFactory();
- JsonParser jsonParser1 = jsonFactory.createJsonParser(str1);
- JsonParser jsonParser2 = jsonFactory.createJsonParser(str2);
- MapGeometry geom1 = GeometryEngine.jsonToGeometry(jsonParser1);
- MapGeometry geom2 = GeometryEngine.jsonToGeometry(jsonParser2);
+ MapGeometry geom1 = GeometryEngine.jsonToGeometry(JsonParserReader.createFromString(str1));
+ MapGeometry geom2 = GeometryEngine.jsonToGeometry(JsonParserReader.createFromString(str2));
double distance = GeometryEngine.distance(geom1.getGeometry(),
geom2.getGeometry(), null);
assertTrue(distance == 0);
diff --git a/unittest/com/esri/core/geometry/TestEditShape.java b/src/test/java/com/esri/core/geometry/TestEditShape.java
similarity index 91%
rename from unittest/com/esri/core/geometry/TestEditShape.java
rename to src/test/java/com/esri/core/geometry/TestEditShape.java
index 94bd5fb2..95b5ea30 100644
--- a/unittest/com/esri/core/geometry/TestEditShape.java
+++ b/src/test/java/com/esri/core/geometry/TestEditShape.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
@@ -17,8 +41,6 @@ protected void tearDown() throws Exception {
@Test
public static void testEditShape() {
{
- // std::shared_ptr poly_base_6
- // = std::make_shared();
// Single part polygon
Polygon poly = new Polygon();
poly.startPath(10, 10);
@@ -183,7 +205,7 @@ public static void testEditShape() {
EditShape editShape = new EditShape();
int geom = editShape.addGeometry(poly);
- editShape.filterClosePoints(0.002, true);
+ editShape.filterClosePoints(0.002, true, false);
Polygon poly2 = (Polygon) editShape.getGeometry(geom);
assertTrue(poly2.isEmpty());
}
@@ -197,7 +219,7 @@ public static void testEditShape() {
EditShape editShape = new EditShape();
int geom = editShape.addGeometry(poly);
- editShape.filterClosePoints(0.002, true);
+ editShape.filterClosePoints(0.002, true, false);
Polygon poly2 = (Polygon) editShape.getGeometry(geom);
assertTrue(!poly2.isEmpty());
}
@@ -211,7 +233,7 @@ public static void testEditShape() {
EditShape editShape = new EditShape();
int geom = editShape.addGeometry(poly);
- editShape.filterClosePoints(0.002, true);
+ editShape.filterClosePoints(0.002, true, false);
Polygon poly2 = (Polygon) editShape.getGeometry(geom);
assertTrue(poly2.isEmpty());
}
@@ -295,7 +317,7 @@ public static void testEditShape() {
EditShape shape = new EditShape();
int g1 = shape.addGeometry(line1);
int g2 = shape.addGeometry(line2);
- CrackAndCluster.execute(shape, 0.001, null);
+ CrackAndCluster.execute(shape, 0.001, null, true);
Polyline chopped_line1 = (Polyline) shape.getGeometry(g1);
Polyline chopped_line2 = (Polyline) shape.getGeometry(g2);
diff --git a/src/test/java/com/esri/core/geometry/TestEnvelope.java b/src/test/java/com/esri/core/geometry/TestEnvelope.java
new file mode 100644
index 00000000..9ee34862
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestEnvelope.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed 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 com.esri.core.geometry;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TestEnvelope
+{
+ @Test
+ /**The function returns the x and y coordinates of the center of the envelope.
+ * If the envelope is empty the point is set to empty otherwise the point is set to the center of the envelope.
+ */
+ public void testGetCeneter(){
+ //xmin,ymin,xmax,ymax of envelope
+ Envelope env1 = new Envelope(1,1, 2, 4);
+ Envelope env2 = new Envelope();
+ Point p = new Point();
+ Point p1 = new Point(1,2);
+
+ /**Tests if the point is correctly set to the center of the envelope, */
+ env1.getCenter(p);
+ assertTrue(p.getX() == 1.5);
+
+ /** Tests if the point is empty because of the envelope is empty */
+ env2.getCenter(p1);
+ assertTrue(p1.isEmpty());
+ }
+ @Test
+ /* Merge takes a Point as input and increas the bouandary of the envelope to contain the point.
+ *If the point is empty the envelope remains the same or if the envelope is empty the coordinates
+ *of the point is assigned to the envelope */
+ public void testMerge(){
+
+ /* To increase the covarege the branch where the envelope is empty can be tested
+ * And that the envelope and the point is not empty */
+ Envelope env1 = new Envelope(1,1, 2, 4);
+ Envelope env2 = new Envelope(1,1, 2, 4);
+ Envelope env3 = new Envelope(1,1, 2, 4);
+ Point p = new Point(100,4);
+
+ /*This should be false since env1 should change depending on point p */
+ env1.merge(p);
+ assertFalse(env1.equals(env2));
+
+ /* This assert should be true since the point is empty and therefore env2 should not change */
+ Point p1 = new Point();
+ env2.merge(p1);
+ assertTrue(env2.equals(env3));
+ }
+
+
+ @Test
+ /** TESTEST ENVELOPE2D **
+ * ClipLine modify a line to be inside a envelope if possible */
+ public void TestClipLine(){
+
+ //checking if segPrama is 0 and the segment is outside of the clipping window
+ //covers first return
+ Envelope2D env0 = new Envelope2D(1, 1, 4, 4);
+ // Reaches the branch where the delta is 0
+ Point2D p1 = new Point2D(2,2);
+ Point2D p2 = new Point2D(2,2);
+
+ int lineExtension = 0;
+ double[] segParams = {3,4};
+ //reaches the branch where boundaryDistances is not 0
+ double[] boundaryDistances = {2.0, 3.0};
+
+ int a = env0.clipLine(p1, p2, lineExtension, segParams, boundaryDistances);
+ //should be true since the points are inside the envelope
+ assertTrue(a == 4);
+
+ // Changes p3 to fit the envelop, the line is on the edge of the envelope
+ Envelope2D env1 = new Envelope2D(1, 1, 4, 4);
+ Point2D p3 = new Point2D(1,10);
+ Point2D p4 = new Point2D(1,1);
+
+ int b = env1.clipLine(p3, p4, lineExtension, segParams, boundaryDistances);
+ assertTrue(b == 1);
+ // the second point is outside and therefore changed
+ Envelope2D env2 = new Envelope2D(1, 1, 4, 4);
+ Point2D p5 = new Point2D(2,2);
+ Point2D p6 = new Point2D(1,10);
+
+ int c = env2.clipLine(p5, p6, lineExtension, segParams, boundaryDistances);
+ assertTrue(c == 2);
+
+ //Both points is outside the envelope and therefore no line is possible to clip, and this should return 0
+ Envelope2D env3 = new Envelope2D(1, 1, 4, 4);
+ Point2D p7 = new Point2D(11,10);
+ Point2D p8 = new Point2D(5,5);
+
+ int d = env3.clipLine(p7, p8, lineExtension, segParams, boundaryDistances);
+ assertTrue(d == 0);
+ }
+
+ @Test
+ public void testSqrDistances(){
+ //the point is on the envelope, which means that the distance is 0
+ Envelope2D env0 = new Envelope2D(1, 1, 4, 4);
+ Point2D p0 = new Point2D(4,4);
+ assertTrue(env0.sqrDistance(p0) == 0.0);
+
+ Envelope2D env1 = new Envelope2D(1, 1, 4, 4);
+ Point2D p1 = new Point2D(1,0);
+
+ assertTrue(env0.sqrDistance(p1) == 1.0);
+
+ }
+ @Test
+ public void testIntersect() {
+ assertIntersection(new Envelope(0, 0, 5, 5), new Envelope(0, 0, 5, 5), new Envelope(0, 0, 5, 5));
+ assertIntersection(new Envelope(0, 0, 5, 5), new Envelope(1, 1, 6, 6), new Envelope(1, 1, 5, 5));
+ assertIntersection(new Envelope(1, 2, 3, 4), new Envelope(0, 0, 2, 3), new Envelope(1, 2, 2, 3));
+
+ assertNoIntersection(new Envelope(), new Envelope());
+ assertNoIntersection(new Envelope(0, 0, 5, 5), new Envelope());
+ assertNoIntersection(new Envelope(), new Envelope(0, 0, 5, 5));
+ }
+
+ @Test
+ public void testEquals() {
+ Envelope env1 = new Envelope(10, 9, 11, 12);
+ Envelope env2 = new Envelope(10, 9, 11, 13);
+ Envelope1D emptyInterval = new Envelope1D();
+ emptyInterval.setEmpty();
+ assertFalse(env1.equals(env2));
+ env1.queryInterval(VertexDescription.Semantics.M, 0).equals(emptyInterval);
+ env2.setCoords(10, 9, 11, 12);
+ assertTrue(env1.equals(env2));
+ env1.addAttribute(VertexDescription.Semantics.M);
+ env1.queryInterval(VertexDescription.Semantics.M, 0).equals(emptyInterval);
+ assertFalse(env1.equals(env2));
+ env2.addAttribute(VertexDescription.Semantics.M);
+ assertTrue(env1.equals(env2));
+ Envelope1D nonEmptyInterval = new Envelope1D();
+ nonEmptyInterval.setCoords(1, 2);
+ env1.setInterval(VertexDescription.Semantics.M, 0, emptyInterval);
+ assertTrue(env1.equals(env2));
+ env2.setInterval(VertexDescription.Semantics.M, 0, emptyInterval);
+ assertTrue(env1.equals(env2));
+ env2.setInterval(VertexDescription.Semantics.M, 0, nonEmptyInterval);
+ assertFalse(env1.equals(env2));
+ env1.setInterval(VertexDescription.Semantics.M, 0, nonEmptyInterval);
+ assertTrue(env1.equals(env2));
+ env1.queryInterval(VertexDescription.Semantics.M, 0).equals(nonEmptyInterval);
+ env1.queryInterval(VertexDescription.Semantics.POSITION, 0).equals(new Envelope1D(10, 11));
+ env1.queryInterval(VertexDescription.Semantics.POSITION, 0).equals(new Envelope1D(9, 13));
+ }
+
+ private static void assertIntersection(Envelope envelope, Envelope other, Envelope intersection) {
+ boolean intersects = envelope.intersect(other);
+ assertTrue(intersects);
+ assertEquals(envelope, intersection);
+ }
+
+ private static void assertNoIntersection(Envelope envelope, Envelope other) {
+ boolean intersects = envelope.intersect(other);
+ assertFalse(intersects);
+ assertTrue(envelope.isEmpty());
+ }
+
+}
+
diff --git a/src/test/java/com/esri/core/geometry/TestEnvelope1D.java b/src/test/java/com/esri/core/geometry/TestEnvelope1D.java
new file mode 100644
index 00000000..4ecd8cbc
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestEnvelope1D.java
@@ -0,0 +1,22 @@
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+public class TestEnvelope1D extends TestCase{
+ @Test
+ public void testCalculateToleranceFromEnvelopeEmpty() {
+ Envelope1D envelope = new Envelope1D();
+ envelope.setEmpty();
+ double tolerance = envelope._calculateToleranceFromEnvelope();
+ assertEquals(100.0 * NumberUtils.doubleEps(), tolerance, 0.0001);
+ }
+
+ @Test
+ public void testCalculateToleranceFromEnvelopeNonEmpty() {
+ Envelope1D envelope = new Envelope1D(2.0, 4.0);
+ double tolerance = envelope._calculateToleranceFromEnvelope();
+ assertEquals(2.220446049250313e-14, tolerance, 1e-10);
+ }
+
+
+}
diff --git a/unittest/com/esri/core/geometry/TestEnvelope2DIntersector.java b/src/test/java/com/esri/core/geometry/TestEnvelope2DIntersector.java
similarity index 89%
rename from unittest/com/esri/core/geometry/TestEnvelope2DIntersector.java
rename to src/test/java/com/esri/core/geometry/TestEnvelope2DIntersector.java
index 4ffd03cf..2f33fadb 100644
--- a/unittest/com/esri/core/geometry/TestEnvelope2DIntersector.java
+++ b/src/test/java/com/esri/core/geometry/TestEnvelope2DIntersector.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import java.util.ArrayList;
@@ -49,7 +73,7 @@ public static void testEnvelope2Dintersector() {
intersector.startConstruction();
for (int i = 0; i < envelopes.size(); i++)
- intersector.addEnvelope(envelopes.get(i));
+ intersector.addEnvelope(i, envelopes.get(i));
intersector.endConstruction();
int count = 0;
@@ -69,7 +93,7 @@ public static void testEnvelope2Dintersector() {
intersector2.setTolerance(0.0);
intersector2.startConstruction();
for (int i = 0; i < envelopes.size(); i++)
- intersector2.addEnvelope(envelopes.get(i));
+ intersector2.addEnvelope(i, envelopes.get(i));
intersector2.endConstruction();
count = 0;
@@ -100,7 +124,7 @@ public static void testEnvelope2Dintersector() {
intersector3.startConstruction();
for (int i = 0; i < envelopes.size(); i++)
- intersector3.addEnvelope(envelopes.get(i));
+ intersector3.addEnvelope(i, envelopes.get(i));
intersector3.endConstruction();
;
count = 0;
@@ -128,7 +152,7 @@ public static void testEnvelope2Dintersector() {
intersector4.startConstruction();
for (int i = 0; i < envelopes.size(); i++)
- intersector4.addEnvelope(envelopes.get(i));
+ intersector4.addEnvelope(i, envelopes.get(i));
intersector4.endConstruction();
count = 0;
@@ -156,7 +180,7 @@ public static void testEnvelope2Dintersector() {
intersector5.startConstruction();
for (int i = 0; i < envelopes.size(); i++)
- intersector5.addEnvelope(envelopes.get(i));
+ intersector5.addEnvelope(i, envelopes.get(i));
intersector5.endConstruction();
count = 0;
@@ -305,12 +329,12 @@ public static void testRandom() {
intersector.startRedConstruction();
for (int i = 0; i < envelopes_red.size(); i++)
- intersector.addRedEnvelope(envelopes_red.get(i));
+ intersector.addRedEnvelope(i, envelopes_red.get(i));
intersector.endRedConstruction();
intersector.startBlueConstruction();
for (int i = 0; i < envelopes_blue.size(); i++)
- intersector.addBlueEnvelope(envelopes_blue.get(i));
+ intersector.addBlueEnvelope(i, envelopes_blue.get(i));
intersector.endBlueConstruction();
while (intersector.next())
diff --git a/unittest/com/esri/core/geometry/TestEquals.java b/src/test/java/com/esri/core/geometry/TestEquals.java
similarity index 83%
rename from unittest/com/esri/core/geometry/TestEquals.java
rename to src/test/java/com/esri/core/geometry/TestEquals.java
index a42abf30..90ed71a0 100644
--- a/unittest/com/esri/core/geometry/TestEquals.java
+++ b/src/test/java/com/esri/core/geometry/TestEquals.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
diff --git a/src/test/java/com/esri/core/geometry/TestEstimateMemorySize.java b/src/test/java/com/esri/core/geometry/TestEstimateMemorySize.java
new file mode 100644
index 00000000..b1b40b22
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestEstimateMemorySize.java
@@ -0,0 +1,193 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+ package com.esri.core.geometry;
+
+import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
+import com.esri.core.geometry.ogc.OGCConcreteGeometryCollection;
+import com.esri.core.geometry.ogc.OGCGeometry;
+import com.esri.core.geometry.ogc.OGCLineString;
+import com.esri.core.geometry.ogc.OGCMultiLineString;
+import com.esri.core.geometry.ogc.OGCMultiPoint;
+import com.esri.core.geometry.ogc.OGCMultiPolygon;
+import com.esri.core.geometry.ogc.OGCPoint;
+import com.esri.core.geometry.ogc.OGCPolygon;
+import org.junit.Test;
+// ClassLayout is GPL with Classpath exception, see http://openjdk.java.net/legal/gplv2+ce.html
+import org.openjdk.jol.info.ClassLayout;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestEstimateMemorySize {
+ @Test
+ public void testInstanceSizes() {
+ assertEquals(getInstanceSize(AttributeStreamOfFloat.class), SizeOf.SIZE_OF_ATTRIBUTE_STREAM_OF_FLOAT);
+ assertEquals(getInstanceSize(AttributeStreamOfDbl.class), SizeOf.SIZE_OF_ATTRIBUTE_STREAM_OF_DBL);
+ assertEquals(getInstanceSize(AttributeStreamOfInt8.class), SizeOf.SIZE_OF_ATTRIBUTE_STREAM_OF_INT8);
+ assertEquals(getInstanceSize(AttributeStreamOfInt16.class), SizeOf.SIZE_OF_ATTRIBUTE_STREAM_OF_INT16);
+ assertEquals(getInstanceSize(AttributeStreamOfInt32.class), SizeOf.SIZE_OF_ATTRIBUTE_STREAM_OF_INT32);
+ assertEquals(getInstanceSize(AttributeStreamOfInt64.class), SizeOf.SIZE_OF_ATTRIBUTE_STREAM_OF_INT64);
+ assertEquals(getInstanceSize(Envelope.class), SizeOf.SIZE_OF_ENVELOPE);
+ assertEquals(getInstanceSize(Envelope2D.class), SizeOf.SIZE_OF_ENVELOPE2D);
+ assertEquals(getInstanceSize(Line.class), SizeOf.SIZE_OF_LINE);
+ assertEquals(getInstanceSize(MultiPath.class), SizeOf.SIZE_OF_MULTI_PATH);
+ assertEquals(getInstanceSize(MultiPathImpl.class), SizeOf.SIZE_OF_MULTI_PATH_IMPL);
+ assertEquals(getInstanceSize(MultiPoint.class), SizeOf.SIZE_OF_MULTI_POINT);
+ assertEquals(getInstanceSize(MultiPointImpl.class), SizeOf.SIZE_OF_MULTI_POINT_IMPL);
+ assertEquals(getInstanceSize(Point.class), SizeOf.SIZE_OF_POINT);
+ assertEquals(getInstanceSize(Polygon.class), SizeOf.SIZE_OF_POLYGON);
+ assertEquals(getInstanceSize(Polyline.class), SizeOf.SIZE_OF_POLYLINE);
+ assertEquals(getInstanceSize(OGCConcreteGeometryCollection.class),
+ SizeOf.SIZE_OF_OGC_CONCRETE_GEOMETRY_COLLECTION);
+ assertEquals(getInstanceSize(OGCLineString.class), SizeOf.SIZE_OF_OGC_LINE_STRING);
+ assertEquals(getInstanceSize(OGCMultiLineString.class), SizeOf.SIZE_OF_OGC_MULTI_LINE_STRING);
+ assertEquals(getInstanceSize(OGCMultiPoint.class), SizeOf.SIZE_OF_OGC_MULTI_POINT);
+ assertEquals(getInstanceSize(OGCMultiPolygon.class), SizeOf.SIZE_OF_OGC_MULTI_POLYGON);
+ assertEquals(getInstanceSize(OGCPoint.class), SizeOf.SIZE_OF_OGC_POINT);
+ assertEquals(getInstanceSize(OGCPolygon.class), SizeOf.SIZE_OF_OGC_POLYGON);
+ assertEquals(getInstanceSize(RasterizedGeometry2DImpl.class), SizeOf.SIZE_OF_RASTERIZED_GEOMETRY_2D_IMPL);
+ assertEquals(getInstanceSize(RasterizedGeometry2DImpl.ScanCallbackImpl.class), SizeOf.SIZE_OF_SCAN_CALLBACK_IMPL);
+ assertEquals(getInstanceSize(Transformation2D.class), SizeOf.SIZE_OF_TRANSFORMATION_2D);
+ assertEquals(getInstanceSize(SimpleRasterizer.class), SizeOf.SIZE_OF_SIMPLE_RASTERIZER);
+ assertEquals(getInstanceSize(SimpleRasterizer.Edge.class), SizeOf.SIZE_OF_EDGE);
+ assertEquals(getInstanceSize(QuadTreeImpl.class), SizeOf.SIZE_OF_QUAD_TREE_IMPL);
+ assertEquals(getInstanceSize(QuadTreeImpl.Data.class), SizeOf.SIZE_OF_DATA);
+ assertEquals(getInstanceSize(StridedIndexTypeCollection.class), SizeOf.SIZE_OF_STRIDED_INDEX_TYPE_COLLECTION);
+ }
+
+ private static long getInstanceSize(Class clazz) {
+ return ClassLayout.parseClass(clazz).instanceSize();
+ }
+
+ @Test
+ public void testPoint() {
+ testGeometry(parseWkt("POINT (1 2)"));
+ }
+
+ @Test
+ public void testEmptyPoint() {
+ testGeometry(parseWkt("POINT EMPTY"));
+ }
+
+ @Test
+ public void testMultiPoint() {
+ testGeometry(parseWkt("MULTIPOINT (0 0, 1 1, 2 3)"));
+ }
+
+ @Test
+ public void testEmptyMultiPoint() {
+ testGeometry(parseWkt("MULTIPOINT EMPTY"));
+ }
+
+ @Test
+ public void testAcceleratedGeometry() {
+ testGeometry(parseWkt("LINESTRING (0 1, 2 3, 4 5)"));
+ }
+
+ @Test
+ public void testEmptyLineString() {
+ testGeometry(parseWkt("LINESTRING EMPTY"));
+ }
+
+ @Test
+ public void testMultiLineString() {
+ testAcceleratedGeometry(parseWkt("MULTILINESTRING ((0 1, 2 3, 4 5), (1 1, 2 2))"));
+ }
+
+ @Test
+ public void testEmptyMultiLineString() {
+ testGeometry(parseWkt("MULTILINESTRING EMPTY"));
+ }
+
+ @Test
+ public void testPolygon() {
+ testAcceleratedGeometry(parseWkt("POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"));
+ }
+
+ @Test
+ public void testEmptyPolygon() {
+ testGeometry(parseWkt("POLYGON EMPTY"));
+ }
+
+ @Test
+ public void testMultiPolygon() {
+ testAcceleratedGeometry(parseWkt("MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))"));
+ }
+
+ @Test
+ public void testEmptyMultiPolygon() {
+ testGeometry(parseWkt("MULTIPOLYGON EMPTY"));
+ }
+
+ @Test
+ public void testGeometryCollection() {
+ testGeometry(parseWkt("GEOMETRYCOLLECTION (POINT(4 6), LINESTRING(4 6,7 10))"));
+ }
+
+ @Test
+ public void testEmptyGeometryCollection() {
+ testGeometry(parseWkt("GEOMETRYCOLLECTION EMPTY"));
+ }
+
+ private void testGeometry(OGCGeometry geometry) {
+ assertTrue(geometry.estimateMemorySize() > 0);
+ }
+
+ private void testAcceleratedGeometry(OGCGeometry geometry) {
+ long initialSize = geometry.estimateMemorySize();
+ assertTrue(initialSize > 0);
+
+ Envelope envelope = new Envelope();
+ geometry.getEsriGeometry().queryEnvelope(envelope);
+
+ long withEnvelopeSize = geometry.estimateMemorySize();
+ assertTrue(withEnvelopeSize > initialSize);
+
+ accelerate(geometry, GeometryAccelerationDegree.enumMild);
+ long mildAcceleratedSize = geometry.estimateMemorySize();
+ assertTrue(mildAcceleratedSize > withEnvelopeSize);
+
+ accelerate(geometry, GeometryAccelerationDegree.enumMedium);
+ long mediumAcceleratedSize = geometry.estimateMemorySize();
+ assertTrue(mediumAcceleratedSize > mildAcceleratedSize);
+
+ accelerate(geometry, GeometryAccelerationDegree.enumHot);
+ long hotAcceleratedSize = geometry.estimateMemorySize();
+ assertTrue(hotAcceleratedSize > mediumAcceleratedSize);
+ }
+
+ private void accelerate(OGCGeometry geometry, GeometryAccelerationDegree accelerationDegree)
+ {
+ Operator relateOperator = OperatorFactoryLocal.getInstance().getOperator(Operator.Type.Relate);
+ boolean accelerated = relateOperator.accelerateGeometry(geometry.getEsriGeometry(), geometry.getEsriSpatialReference(), accelerationDegree);
+ assertTrue(accelerated);
+ }
+
+ private static OGCGeometry parseWkt(String wkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ geometry.setSpatialReference(null);
+ return geometry;
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestFailed.java b/src/test/java/com/esri/core/geometry/TestFailed.java
similarity index 67%
rename from unittest/com/esri/core/geometry/TestFailed.java
rename to src/test/java/com/esri/core/geometry/TestFailed.java
index aac65c3c..05bede19 100644
--- a/unittest/com/esri/core/geometry/TestFailed.java
+++ b/src/test/java/com/esri/core/geometry/TestFailed.java
@@ -1,65 +1,88 @@
-package com.esri.core.geometry;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestFailed extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public void testCenterXY() {
- Envelope env = new Envelope(-130, 30, -70, 50);
- assertEquals(-100, env.getCenterX(), 0);
- assertEquals(40, env.getCenterY(), 0);
- }
-
- @Test
- public void testGeometryOperationSupport() {
- Geometry baseGeom = new Point(-130, 10);
- Geometry comparisonGeom = new Point(-130, 10);
- SpatialReference sr = SpatialReference.create(4326);
-
- @SuppressWarnings("unused")
- Geometry diffGeom = null;
- int noException = 1; // no exception
- try {
- diffGeom = GeometryEngine.difference(baseGeom, comparisonGeom, sr);
-
- } catch (IllegalArgumentException ex) {
- noException = 0;
- } catch (GeometryException ex) {
- System.out.println(ex.internalCode);
- noException = 0;
- }
- assertEquals(noException, 1);
- }
-
- @Test
- public void TestIntersection() {
- OperatorIntersects op = (OperatorIntersects) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Intersects);
- Polygon polygon = new Polygon();
- // outer ring1
- polygon.startPath(0, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(20, 0);
-
- Point point1 = new Point(15, 10);
- Point point2 = new Point(2, 10);
- Point point3 = new Point(5, 5);
- boolean res = op.execute(polygon, point1, null, null);
- assertTrue(!res);
- res = op.execute(polygon, point2, null, null);
- assertTrue(!res);
- res = op.execute(polygon, point3, null, null);
- assertTrue(res);
- }
-}
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class TestFailed extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testCenterXY() {
+ Envelope env = new Envelope(-130, 30, -70, 50);
+ assertEquals(-100, env.getCenterX(), 0);
+ assertEquals(40, env.getCenterY(), 0);
+ }
+
+ @Test
+ public void testGeometryOperationSupport() {
+ Geometry baseGeom = new Point(-130, 10);
+ Geometry comparisonGeom = new Point(-130, 10);
+ SpatialReference sr = SpatialReference.create(4326);
+
+ @SuppressWarnings("unused")
+ Geometry diffGeom = null;
+ int noException = 1; // no exception
+ try {
+ diffGeom = GeometryEngine.difference(baseGeom, comparisonGeom, sr);
+
+ } catch (IllegalArgumentException ex) {
+ noException = 0;
+ } catch (GeometryException ex) {
+ noException = 0;
+ }
+ assertEquals(noException, 1);
+ }
+
+ @Test
+ public void TestIntersection() {
+ OperatorIntersects op = (OperatorIntersects) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.Intersects);
+ Polygon polygon = new Polygon();
+ // outer ring1
+ polygon.startPath(0, 0);
+ polygon.lineTo(10, 10);
+ polygon.lineTo(20, 0);
+
+ Point point1 = new Point(15, 10);
+ Point point2 = new Point(2, 10);
+ Point point3 = new Point(5, 5);
+ boolean res = op.execute(polygon, point1, null, null);
+ assertTrue(!res);
+ res = op.execute(polygon, point2, null, null);
+ assertTrue(!res);
+ res = op.execute(polygon, point3, null, null);
+ assertTrue(res);
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestGeneralize.java b/src/test/java/com/esri/core/geometry/TestGeneralize.java
similarity index 64%
rename from unittest/com/esri/core/geometry/TestGeneralize.java
rename to src/test/java/com/esri/core/geometry/TestGeneralize.java
index c7316e74..34d497e4 100644
--- a/unittest/com/esri/core/geometry/TestGeneralize.java
+++ b/src/test/java/com/esri/core/geometry/TestGeneralize.java
@@ -1,6 +1,31 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
+
import org.junit.Test;
public class TestGeneralize extends TestCase {
@@ -90,4 +115,29 @@ public static void test2() {
assertTrue(points[0].x == 0 && points[0].y == 0);
assertTrue(points[1].x == 0 && points[1].y == 10);
}
+
+ @Test
+ public static void testLargeDeviation() {
+ {
+ Polygon input_polygon = new Polygon();
+ input_polygon
+ .addEnvelope(Envelope2D.construct(0, 0, 20, 10), false);
+ Geometry densified_geom = OperatorDensifyByLength.local().execute(
+ input_polygon, 1, null);
+ Geometry geom = OperatorGeneralize.local().execute(densified_geom,
+ 1, true, null);
+ int pc = ((MultiPath) geom).getPointCount();
+ assertTrue(pc == 4);
+
+ Geometry large_dev1 = OperatorGeneralize.local().execute(
+ densified_geom, 40, true, null);
+ int pc1 = ((MultiPath) large_dev1).getPointCount();
+ assertTrue(pc1 == 0);
+
+ Geometry large_dev2 = OperatorGeneralize.local().execute(
+ densified_geom, 40, false, null);
+ int pc2 = ((MultiPath) large_dev2).getPointCount();
+ assertTrue(pc2 == 3);
+ }
+ }
}
diff --git a/src/test/java/com/esri/core/geometry/TestGeodetic.java b/src/test/java/com/esri/core/geometry/TestGeodetic.java
new file mode 100644
index 00000000..93185af9
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestGeodetic.java
@@ -0,0 +1,129 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+public class TestGeodetic extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testTriangleLength() {
+ Point pt_0 = new Point(10, 10);
+ Point pt_1 = new Point(20, 20);
+ Point pt_2 = new Point(20, 10);
+ double length = 0.0;
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_0, pt_1);
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_1, pt_2);
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_2, pt_0);
+ assertTrue(Math.abs(length - 3744719.4094597572) < 1e-12 * 3744719.4094597572);
+ }
+
+ @Test
+ public void testRotationInvariance() {
+ Point pt_0 = new Point(10, 40);
+ Point pt_1 = new Point(20, 60);
+ Point pt_2 = new Point(20, 40);
+ double length = 0.0;
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_0, pt_1);
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_1, pt_2);
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_2, pt_0);
+ assertTrue(Math.abs(length - 5409156.3896271614) < 1e-12 * 5409156.3896271614);
+
+ for (int i = -540; i < 540; i += 5) {
+ pt_0.setXY(i + 10, 40);
+ pt_1.setXY(i + 20, 60);
+ pt_2.setXY(i + 20, 40);
+ length = 0.0;
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_0, pt_1);
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_1, pt_2);
+ length += GeometryEngine.geodesicDistanceOnWGS84(pt_2, pt_0);
+ assertTrue(Math.abs(length - 5409156.3896271614) < 1e-12 * 5409156.3896271614);
+ }
+ }
+
+ @Test
+ public void testDistanceFailure() {
+ {
+ Point p1 = new Point(-60.668485, -31.996013333333334);
+ Point p2 = new Point(119.13731666666666, 32.251583333333336);
+ double d = GeometryEngine.geodesicDistanceOnWGS84(p1, p2);
+ assertTrue(Math.abs(d - 19973410.50579736) < 1e-13 * 19973410.50579736);
+ }
+
+ {
+ Point p1 = new Point(121.27343833333333, 27.467438333333334);
+ Point p2 = new Point(-58.55804833333333, -27.035613333333334);
+ double d = GeometryEngine.geodesicDistanceOnWGS84(p1, p2);
+ assertTrue(Math.abs(d - 19954707.428360686) < 1e-13 * 19954707.428360686);
+ }
+
+ {
+ Point p1 = new Point(-53.329865, -36.08110166666667);
+ Point p2 = new Point(126.52895166666667, 35.97385);
+ double d = GeometryEngine.geodesicDistanceOnWGS84(p1, p2);
+ assertTrue(Math.abs(d - 19990586.700431127) < 1e-13 * 19990586.700431127);
+ }
+
+ {
+ Point p1 = new Point(-4.7181166667, 36.1160166667);
+ Point p2 = new Point(175.248925, -35.7606716667);
+ double d = GeometryEngine.geodesicDistanceOnWGS84(p1, p2);
+ assertTrue(Math.abs(d - 19964450.206594173) < 1e-12 * 19964450.206594173);
+ }
+ }
+
+ @Test
+ public void testLengthAccurateCR191313() {
+ /*
+ * // random_test(); OperatorFactoryLocal engine =
+ * OperatorFactoryLocal.getInstance(); //TODO: Make this:
+ * OperatorShapePreservingLength geoLengthOp =
+ * (OperatorShapePreservingLength)
+ * factory.getOperator(Operator.Type.ShapePreservingLength);
+ * SpatialReference spatialRef = SpatialReference.create(102631);
+ * //[6097817.59407673
+ * ,17463475.2931517],[-1168053.34617516,11199801.3734424
+ * ]]],"spatialReference":{"wkid":102631}
+ *
+ * Polyline polyline = new Polyline();
+ * polyline.startPath(6097817.59407673, 17463475.2931517);
+ * polyline.lineTo(-1168053.34617516, 11199801.3734424); double length =
+ * geoLengthOp.execute(polyline, spatialRef, null);
+ * assertTrue(Math.abs(length - 2738362.3249366437) < 2e-9 * length);
+ */
+ }
+
+}
diff --git a/src/test/java/com/esri/core/geometry/TestGeomToGeoJson.java b/src/test/java/com/esri/core/geometry/TestGeomToGeoJson.java
new file mode 100644
index 00000000..83271d5b
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestGeomToGeoJson.java
@@ -0,0 +1,508 @@
+/*
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.ogc.*;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestGeomToGeoJson extends TestCase {
+ OperatorFactoryLocal factory = OperatorFactoryLocal.getInstance();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testPoint() {
+ Point p = new Point(10.0, 20.0);
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[10,20]}", result);
+ }
+
+ @Test
+ public void testEmptyPoint() {
+ Point p = new Point();
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[]}", result);
+ }
+
+ @Test
+ public void testPointGeometryEngine() {
+ Point p = new Point(10.0, 20.0);
+ String result = GeometryEngine.geometryToGeoJson(p);
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[10,20]}", result);
+ }
+
+ @Test
+ public void testOGCPoint() {
+ Point p = new Point(10.0, 20.0);
+ OGCGeometry ogcPoint = new OGCPoint(p, null);
+ String result = ogcPoint.asGeoJson();
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[10,20],\"crs\":null}", result);
+ }
+
+ @Test
+ public void testMultiPoint() {
+ MultiPoint mp = new MultiPoint();
+ mp.add(10.0, 20.0);
+ mp.add(20.0, 30.0);
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(mp);
+ assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[10,20],[20,30]]}", result);
+ }
+
+ @Test
+ public void testEmptyMultiPoint() {
+ MultiPoint mp = new MultiPoint();
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(mp);
+ assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[]}", result);
+ }
+
+ @Test
+ public void testMultiPointGeometryEngine() {
+ MultiPoint mp = new MultiPoint();
+ mp.add(10.0, 20.0);
+ mp.add(20.0, 30.0);
+ String result = GeometryEngine.geometryToGeoJson(mp);
+ assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[10,20],[20,30]]}", result);
+ }
+
+ @Test
+ public void testOGCMultiPoint() {
+ MultiPoint mp = new MultiPoint();
+ mp.add(10.0, 20.0);
+ mp.add(20.0, 30.0);
+ OGCMultiPoint ogcMultiPoint = new OGCMultiPoint(mp, null);
+ String result = ogcMultiPoint.asGeoJson();
+ assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[10,20],[20,30]],\"crs\":null}", result);
+ }
+
+ @Test
+ public void testPolyline() {
+ Polyline p = new Polyline();
+ p.startPath(100.0, 0.0);
+ p.lineTo(101.0, 0.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(100.0, 1.0);
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100,0],[101,0],[101,1],[100,1]]}", result);
+ }
+
+ @Test
+ public void testEmptyPolyline() {
+ Polyline p = new Polyline();
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"LineString\",\"coordinates\":[]}", result);
+ }
+
+ @Test
+ public void testPolylineGeometryEngine() {
+ Polyline p = new Polyline();
+ p.startPath(100.0, 0.0);
+ p.lineTo(101.0, 0.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(100.0, 1.0);
+ String result = GeometryEngine.geometryToGeoJson(p);
+ assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100,0],[101,0],[101,1],[100,1]]}", result);
+ }
+
+ @Test
+ public void testOGCLineString() {
+ Polyline p = new Polyline();
+ p.startPath(100.0, 0.0);
+ p.lineTo(101.0, 0.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(100.0, 1.0);
+ OGCLineString ogcLineString = new OGCLineString(p, 0, null);
+ String result = ogcLineString.asGeoJson();
+ assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100,0],[101,0],[101,1],[100,1]],\"crs\":null}", result);
+ }
+
+ @Test
+ public void testOGCMultiLineStringCRS() throws IOException {
+ Polyline p = new Polyline();
+ p.startPath(100.0, 0.0);
+ p.lineTo(101.0, 0.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(100.0, 1.0);
+
+ OGCMultiLineString multiLineString = new OGCMultiLineString(p, SpatialReference.create(4326));
+
+ String result = multiLineString.asGeoJson();
+ assertEquals("{\"type\":\"MultiLineString\",\"coordinates\":[[[100,0],[101,0],[101,1],[100,1]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}", result);
+ }
+
+ @Test
+ public void testPolygon() {
+ Polygon p = new Polygon();
+ p.startPath(100.0, 0.0);
+ p.lineTo(101.0, 0.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(100.0, 1.0);
+ p.closePathWithLine();
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[100,1],[101,1],[101,0],[100,0]]]}", result);
+ }
+
+ @Test
+ public void testPolygonWithHole() {
+ Polygon p = new Polygon();
+
+ //exterior ring - has to be clockwise for Esri
+ p.startPath(100.0, 0.0);
+ p.lineTo(100.0, 1.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(101.0, 0.0);
+ p.closePathWithLine();
+
+ //hole - counterclockwise for Esri
+ p.startPath(100.2, 0.2);
+ p.lineTo(100.8, 0.2);
+ p.lineTo(100.8, 0.8);
+ p.lineTo(100.2, 0.8);
+ p.closePathWithLine();
+
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[101,0],[101,1],[100,1],[100,0]],[[100.2,0.2],[100.2,0.8],[100.8,0.8],[100.8,0.2],[100.2,0.2]]]}", result);
+ }
+
+ @Test
+ public void testPolygonWithHoleReversed() {
+ Polygon p = new Polygon();
+
+ //exterior ring - has to be clockwise for Esri
+ p.startPath(100.0, 0.0);
+ p.lineTo(100.0, 1.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(101.0, 0.0);
+ p.closePathWithLine();
+
+ //hole - counterclockwise for Esri
+ p.startPath(100.2, 0.2);
+ p.lineTo(100.8, 0.2);
+ p.lineTo(100.8, 0.8);
+ p.lineTo(100.2, 0.8);
+ p.closePathWithLine();
+
+ p.reverseAllPaths();//make it reversed. Exterior ring - ccw, hole - cw.
+
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[100,1],[101,1],[101,0],[100,0]],[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]}", result);
+ }
+
+ @Test
+ public void testMultiPolygon() throws IOException {
+ JsonFactory jsonFactory = new JsonFactory();
+
+ //String geoJsonPolygon = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-100,-100],[-100,100],[100,100],[100,-100],[-100,-100]],[[-90,-90],[90,90],[-90,90],[90,-90],[-90,-90]]],[[[-10.0,-10.0],[-10.0,10.0],[10.0,10.0],[10.0,-10.0],[-10.0,-10.0]]]]}";
+ String esriJsonPolygon = "{\"rings\": [[[-100, -100], [-100, 100], [100, 100], [100, -100], [-100, -100]], [[-90, -90], [90, 90], [-90, 90], [90, -90], [-90, -90]], [[-10, -10], [-10, 10], [10, 10], [10, -10], [-10, -10]]]}";
+
+ JsonParser parser = jsonFactory.createParser(esriJsonPolygon);
+ MapGeometry parsedPoly = GeometryEngine.jsonToGeometry(parser);
+ //MapGeometry parsedPoly = GeometryEngine.geometryFromGeoJson(jsonPolygon, 0, Geometry.Type.Polygon);
+
+ Polygon poly = (Polygon) parsedPoly.getGeometry();
+
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ //String result = exporter.execute(parsedPoly.getGeometry());
+ String result = exporter.execute(poly);
+ assertEquals("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-100,-100],[100,-100],[100,100],[-100,100],[-100,-100]],[[-90,-90],[90,-90],[-90,90],[90,90],[-90,-90]]],[[[-10,-10],[10,-10],[10,10],[-10,10],[-10,-10]]]]}", result);
+ }
+
+ @Test
+ public void testOGCMultiPolygonCRS() throws IOException {
+ JsonFactory jsonFactory = new JsonFactory();
+
+ String esriJsonPolygon = "{\"rings\": [[[-100, -100], [-100, 100], [100, 100], [100, -100], [-100, -100]], [[-90, -90], [90, 90], [-90, 90], [90, -90], [-90, -90]], [[-10, -10], [-10, 10], [10, 10], [10, -10], [-10, -10]]]}";
+
+ JsonParser parser = jsonFactory.createParser(esriJsonPolygon);
+ MapGeometry parsedPoly = GeometryEngine.jsonToGeometry(parser);
+
+ parsedPoly.setSpatialReference(SpatialReference.create(4326));
+ Polygon poly = (Polygon) parsedPoly.getGeometry();
+ OGCMultiPolygon multiPolygon = new OGCMultiPolygon(poly, parsedPoly.getSpatialReference());
+
+
+ String result = multiPolygon.asGeoJson();
+ assertEquals("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-100,-100],[100,-100],[100,100],[-100,100],[-100,-100]],[[-90,-90],[90,-90],[-90,90],[90,90],[-90,-90]]],[[[-10,-10],[10,-10],[10,10],[-10,10],[-10,-10]]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}", result);
+ }
+
+
+ @Test
+ public void testEmptyPolygon() {
+ Polygon p = new Polygon();
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(p);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[]}", result);
+
+ MapGeometry imported = OperatorImportFromGeoJson.local().execute(0, Geometry.Type.Unknown, result, null);
+ assertTrue(imported.getGeometry().isEmpty());
+ assertTrue(imported.getGeometry().getType() == Geometry.Type.Polygon);
+ }
+
+ @Test
+ public void testPolygonGeometryEngine() {
+ Polygon p = new Polygon();
+ p.startPath(100.0, 0.0);
+ p.lineTo(101.0, 0.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(100.0, 1.0);
+ p.closePathWithLine();
+ String result = GeometryEngine.geometryToGeoJson(p);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[100,1],[101,1],[101,0],[100,0]]]}", result);
+ }
+
+ @Test
+ public void testOGCPolygon() {
+ Polygon p = new Polygon();
+ p.startPath(100.0, 0.0);
+ p.lineTo(101.0, 0.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(100.0, 1.0);
+ p.closePathWithLine();
+ OGCPolygon ogcPolygon = new OGCPolygon(p, null);
+ String result = ogcPolygon.asGeoJson();
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[100,1],[101,1],[101,0],[100,0]]],\"crs\":null}", result);
+ }
+
+ @Test
+ public void testPolygonWithHoleGeometryEngine() {
+ Polygon p = new Polygon();
+
+ p.startPath(100.0, 0.0);//clockwise exterior
+ p.lineTo(100.0, 1.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(101.0, 0.0);
+ p.closePathWithLine();
+
+ p.startPath(100.2, 0.2);//counterclockwise hole
+ p.lineTo(100.8, 0.2);
+ p.lineTo(100.8, 0.8);
+ p.lineTo(100.2, 0.8);
+ p.closePathWithLine();
+
+ String result = GeometryEngine.geometryToGeoJson(p);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[101,0],[101,1],[100,1],[100,0]],[[100.2,0.2],[100.2,0.8],[100.8,0.8],[100.8,0.2],[100.2,0.2]]]}", result);
+ }
+
+ @Test
+ public void testPolylineWithTwoPaths() {
+ Polyline p = new Polyline();
+
+ p.startPath(100.0, 0.0);
+ p.lineTo(100.0, 1.0);
+
+ p.startPath(100.2, 0.2);
+ p.lineTo(100.8, 0.2);
+
+ String result = GeometryEngine.geometryToGeoJson(p);
+ assertEquals("{\"type\":\"MultiLineString\",\"coordinates\":[[[100,0],[100,1]],[[100.2,0.2],[100.8,0.2]]]}", result);
+ }
+
+ @Test
+ public void testOGCPolygonWithHole() {
+ Polygon p = new Polygon();
+
+ p.startPath(100.0, 0.0);
+ p.lineTo(100.0, 1.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(101.0, 0.0);
+ p.closePathWithLine();
+
+ p.startPath(100.2, 0.2);
+ p.lineTo(100.8, 0.2);
+ p.lineTo(100.8, 0.8);
+ p.lineTo(100.2, 0.8);
+ p.closePathWithLine();
+
+ OGCPolygon ogcPolygon = new OGCPolygon(p, null);
+ String result = ogcPolygon.asGeoJson();
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[101,0],[101,1],[100,1],[100,0]],[[100.2,0.2],[100.2,0.8],[100.8,0.8],[100.8,0.2],[100.2,0.2]]],\"crs\":null}", result);
+ }
+
+ @Test
+ public void testOGCPolygonWithHoleCRS() {
+ Polygon p = new Polygon();
+
+ p.startPath(100.0, 0.0);
+ p.lineTo(100.0, 1.0);
+ p.lineTo(101.0, 1.0);
+ p.lineTo(101.0, 0.0);
+ p.closePathWithLine();
+
+ p.startPath(100.2, 0.2);
+ p.lineTo(100.8, 0.2);
+ p.lineTo(100.8, 0.8);
+ p.lineTo(100.2, 0.8);
+ p.closePathWithLine();
+
+ SpatialReference sr = SpatialReference.create(4326);
+
+ OGCPolygon ogcPolygon = new OGCPolygon(p, sr);
+ String result = ogcPolygon.asGeoJson();
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[101,0],[101,1],[100,1],[100,0]],[[100.2,0.2],[100.2,0.8],[100.8,0.8],[100.8,0.2],[100.2,0.2]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}", result);
+ }
+
+ @Test
+ public void testGeometryCollection() {
+ SpatialReference sr = SpatialReference.create(4326);
+
+ StringBuilder geometrySb = new StringBuilder();
+ geometrySb
+ .append("{\"type\" : \"GeometryCollection\", \"geometries\" : [");
+
+ OGCPoint point = new OGCPoint(new Point(1.0, 1.0), sr);
+ assertEquals("{\"x\":1,\"y\":1,\"spatialReference\":{\"wkid\":4326}}",
+ point.asJson());
+ assertEquals(
+ "{\"type\":\"Point\",\"coordinates\":[1,1],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}",
+ point.asGeoJson());
+ geometrySb.append(point.asGeoJson()).append(", ");
+
+ OGCLineString line = new OGCLineString(new Polyline(
+ new Point(1.0, 1.0), new Point(2.0, 2.0)), 0, sr);
+ assertEquals(
+ "{\"paths\":[[[1,1],[2,2]]],\"spatialReference\":{\"wkid\":4326}}",
+ line.asJson());
+ assertEquals(
+ "{\"type\":\"LineString\",\"coordinates\":[[1,1],[2,2]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}",
+ line.asGeoJson());
+ geometrySb.append(line.asGeoJson()).append(", ");
+
+ Polygon p = new Polygon();
+ p.startPath(1.0, 1.0);
+ p.lineTo(2.0, 2.0);
+ p.lineTo(3.0, 1.0);
+ p.lineTo(2.0, 0.0);
+
+ OGCPolygon polygon = new OGCPolygon(p, sr);
+ assertEquals(
+ "{\"rings\":[[[1,1],[2,2],[3,1],[2,0],[1,1]]],\"spatialReference\":{\"wkid\":4326}}",
+ polygon.asJson());
+ assertEquals(
+ "{\"type\":\"Polygon\",\"coordinates\":[[[1,1],[2,0],[3,1],[2,2],[1,1]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}",
+ polygon.asGeoJson());
+ geometrySb.append(polygon.asGeoJson()).append("]}");
+
+ List geoms = new ArrayList(3);
+ geoms.add(point);
+ geoms.add(line);
+ geoms.add(polygon);
+ OGCConcreteGeometryCollection collection = new OGCConcreteGeometryCollection(
+ geoms, sr);
+ String s2 = collection.asGeoJson();
+
+ assertEquals("{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Point\",\"coordinates\":[1,1]},{\"type\":\"LineString\",\"coordinates\":[[1,1],[2,2]]},{\"type\":\"Polygon\",\"coordinates\":[[[1,1],[2,0],[3,1],[2,2],[1,1]]]}],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}", collection.asGeoJson());
+ }
+
+ @Test
+ public void testEmptyGeometryCollection() {
+ SpatialReference sr = SpatialReference.create(4326);
+ OGCConcreteGeometryCollection collection = new OGCConcreteGeometryCollection(
+ new ArrayList(), sr);
+ String s2 = collection.asGeoJson();
+ assertEquals(
+ "{\"type\":\"GeometryCollection\",\"geometries\":[],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}",
+ collection.asGeoJson());
+ }
+
+ //Envelope is exported as a polygon (we don't support bbox, as it is not a GeoJson geometry, but simply a field)!
+ @Test
+ public void testEnvelope() {
+ Envelope e = new Envelope();
+ e.setCoords(-180.0, -90.0, 180.0, 90.0);
+ String result = OperatorExportToGeoJson.local().execute(e);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[-180,-90],[180,-90],[180,90],[-180,90],[-180,-90]]]}", result);
+ }
+
+ @Test
+ public void testEmptyEnvelope() {
+ Envelope e = new Envelope();
+ String result = OperatorExportToGeoJson.local().execute(e);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[]}", result);
+ }
+
+ @Test
+ public void testEnvelopeGeometryEngine() {
+ Envelope e = new Envelope();
+ e.setCoords(-180.0, -90.0, 180.0, 90.0);
+ String result = GeometryEngine.geometryToGeoJson(e);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[-180,-90],[180,-90],[180,90],[-180,90],[-180,-90]]]}", result);
+ }
+
+ @Test
+ public void testOldCRS() {
+ String inputStr = "{\"type\":\"Polygon\",\"coordinates\":[[[-180,-90],[180,-90],[180,90],[-180,90],[-180,-90]]], \"crs\":\"EPSG:4267\"}";
+ MapGeometry mg = OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.Unknown, inputStr, null);
+ String result = GeometryEngine.geometryToGeoJson(mg.getSpatialReference(), mg.getGeometry());
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[-180,-90],[180,-90],[180,90],[-180,90],[-180,-90]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4267\"}}}", result);
+ }
+
+ // bbox is not supported anymore.
+ // @Test
+ // public void testEnvelope() {
+ // Envelope e = new Envelope();
+ // e.setCoords(-180.0, -90.0, 180.0, 90.0);
+ // OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ // String result = exporter.execute(e);
+ // assertEquals("{\"bbox\":[-180.0,-90.0,180.0,90.0]}", result);
+ // }
+ //
+ // @Test
+ // public void testEmptyEnvelope() {
+ // Envelope e = new Envelope();
+ // OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
+ // String result = exporter.execute(e);
+ // assertEquals("{\"bbox\":null}", result);
+ // }
+ //
+ // @Test
+ // public void testEnvelopeGeometryEngine() {
+ // Envelope e = new Envelope();
+ // e.setCoords(-180.0, -90.0, 180.0, 90.0);
+ // String result = GeometryEngine.geometryToGeoJson(e);
+ // assertEquals("{\"bbox\":[-180.0,-90.0,180.0,90.0]}", result);
+ // }
+
+}
diff --git a/unittest/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java b/src/test/java/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
similarity index 85%
rename from unittest/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
rename to src/test/java/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
index 90277da9..1a0bf432 100644
--- a/unittest/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
+++ b/src/test/java/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
@@ -1,579 +1,589 @@
-package com.esri.core.geometry;
-
-import java.io.IOException;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestGeomToJSonExportSRFromWkiOrWkt_CR181369 extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- JsonFactory factory = new JsonFactory();
- SpatialReference spatialReferenceWebMerc1 = SpatialReference.create(102100);
- SpatialReference spatialReferenceWebMerc2 = SpatialReference
- .create(spatialReferenceWebMerc1.getLatestID());
- SpatialReference spatialReferenceWGS84 = SpatialReference.create(4326);
-
- @Test
- public void testGeomToJSonExportSRFromWkiOrWkt_CR181369()
- throws JsonParseException, IOException {
- testPoint();
- testPolyline();
- testPolygon();
- testEnvelope();
- testMultiPoint();
- testCR181369();
- // These tests return the result of a method called
- // checkResultSpatialRef.
- // However, the tests pass or fail regardless of what that method
- // returns.
- }
-
- boolean testPoint() throws JsonParseException, IOException {
- boolean bAnswer = true;
- Point point1 = new Point(10.0, 20.0);
- Point pointEmpty = new Point();
- {
- JsonParser pointWebMerc1Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWebMerc1, point1));
- MapGeometry pointWebMerc1MP = GeometryEngine
- .jsonToGeometry(pointWebMerc1Parser);
- assertTrue(point1.getX() == ((Point) pointWebMerc1MP.getGeometry())
- .getX());
- assertTrue(point1.getY() == ((Point) pointWebMerc1MP.getGeometry())
- .getY());
- assertTrue(spatialReferenceWebMerc1.getID() == pointWebMerc1MP
- .getSpatialReference().getID()
- || pointWebMerc1MP.getSpatialReference().getID() == 3857);
-
- if (!checkResultSpatialRef(pointWebMerc1MP, 102100, 3857)) {
- bAnswer = false;
- }
-
- pointWebMerc1Parser = factory.createJsonParser(GeometryEngine
- .geometryToJson(null, point1));
- pointWebMerc1MP = GeometryEngine
- .jsonToGeometry(pointWebMerc1Parser);
- assertTrue(null == pointWebMerc1MP.getSpatialReference());
-
- if (pointWebMerc1MP.getSpatialReference() != null) {
- if (!checkResultSpatialRef(pointWebMerc1MP, 102100, 3857)) {
- bAnswer = false;
- }
- }
-
- String pointEmptyString = GeometryEngine.geometryToJson(
- spatialReferenceWebMerc1, pointEmpty);
- pointWebMerc1Parser = factory.createJsonParser(pointEmptyString);
- // FIXME
- // pointWebMerc1MP =
- // GeometryEngine.jsonToGeometry(pointWebMerc1Parser);
- // assertTrue(pointWebMerc1MP.getGeometry().isEmpty());
- // assertTrue(spatialReferenceWebMerc1.getID() ==
- // pointWebMerc1MP.getSpatialReference().getID());
- }
-
- JsonParser pointWebMerc2Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWebMerc2, point1));
- MapGeometry pointWebMerc2MP = GeometryEngine
- .jsonToGeometry(pointWebMerc2Parser);
- assertTrue(point1.getX() == ((Point) pointWebMerc2MP.getGeometry())
- .getX());
- assertTrue(point1.getY() == ((Point) pointWebMerc2MP.getGeometry())
- .getY());
- assertTrue(spatialReferenceWebMerc2.getLatestID() == pointWebMerc2MP
- .getSpatialReference().getLatestID());
- if (!checkResultSpatialRef(pointWebMerc2MP,
- spatialReferenceWebMerc2.getLatestID(), 0)) {
- bAnswer = false;
- }
-
- {
- JsonParser pointWgs84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, point1));
- MapGeometry pointWgs84MP = GeometryEngine
- .jsonToGeometry(pointWgs84Parser);
- assertTrue(point1.getX() == ((Point) pointWgs84MP.getGeometry())
- .getX());
- assertTrue(point1.getY() == ((Point) pointWgs84MP.getGeometry())
- .getY());
- assertTrue(spatialReferenceWGS84.getID() == pointWgs84MP
- .getSpatialReference().getID());
- if (!checkResultSpatialRef(pointWgs84MP, 4326, 0)) {
- bAnswer = false;
- }
- }
-
- {
- Point p = new Point();
- String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
- p);
- assertTrue(s
- .equals("{\"x\":null,\"y\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
-
- p.addAttribute(VertexDescription.Semantics.Z);
- p.addAttribute(VertexDescription.Semantics.M);
- s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
- assertTrue(s
- .equals("{\"x\":null,\"y\":null,\"z\":null,\"m\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
-
- }
-
- {
- Point p = new Point(10.0, 20.0, 30.0);
- p.addAttribute(VertexDescription.Semantics.M);
- String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
- p);
- assertTrue(s
- .equals("{\"x\":10.0,\"y\":20.0,\"z\":30.0,\"m\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
- }
-
- {// import
- String s = "{\"x\":0.0,\"y\":1.0,\"z\":5.0,\"m\":11.0,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}";
- JsonParser parser = factory.createJsonParser(s);
- MapGeometry map_pt = GeometryEngine.jsonToGeometry(parser);
- Point pt = (Point) map_pt.getGeometry();
- assertTrue(pt.getX() == 0.0);
- assertTrue(pt.getY() == 1.0);
- assertTrue(pt.getZ() == 5.0);
- assertTrue(pt.getM() == 11.0);
- }
-
- {
- String s = "{\"x\" : 5.0, \"y\" : null, \"spatialReference\" : {\"wkid\" : 4326}} ";
- JsonParser parser = factory.createJsonParser(s);
- MapGeometry map_pt = GeometryEngine.jsonToGeometry(parser);
- Point pt = (Point) map_pt.getGeometry();
- assertTrue(pt.isEmpty());
- SpatialReference spatial_reference = map_pt.getSpatialReference();
- assertTrue(spatial_reference.getID() == 4326);
- }
-
- return bAnswer;
- }
-
- boolean testMultiPoint() throws JsonParseException, IOException {
- boolean bAnswer = true;
-
- MultiPoint multiPoint1 = new MultiPoint();
- multiPoint1.add(-97.06138, 32.837);
- multiPoint1.add(-97.06133, 32.836);
- multiPoint1.add(-97.06124, 32.834);
- multiPoint1.add(-97.06127, 32.832);
-
- {
- String s = GeometryEngine.geometryToJson(spatialReferenceWGS84,
- multiPoint1);
- JsonParser mPointWgs84Parser = factory.createJsonParser(s);
- MapGeometry mPointWgs84MP = GeometryEngine
- .jsonToGeometry(mPointWgs84Parser);
- assertTrue(multiPoint1.getPointCount() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPointCount());
- assertTrue(multiPoint1.getPoint(0).getX() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(0).getX());
- assertTrue(multiPoint1.getPoint(0).getY() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(0).getY());
- int lastIndex = multiPoint1.getPointCount() - 1;
- assertTrue(multiPoint1.getPoint(lastIndex).getX() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(lastIndex).getX());
- assertTrue(multiPoint1.getPoint(lastIndex).getY() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(lastIndex).getY());
-
- assertTrue(spatialReferenceWGS84.getID() == mPointWgs84MP
- .getSpatialReference().getID());
- if (!checkResultSpatialRef(mPointWgs84MP, 4326, 0)) {
- bAnswer = false;
- }
-
- // FIXME
- // MultiPoint mPointEmpty = new MultiPoint();
- // String mPointEmptyString =
- // GeometryEngine.geometryToJson(spatialReferenceWGS84,
- // mPointEmpty);
- // mPointWgs84Parser = factory.createJsonParser(mPointEmptyString);
- }
-
- {
- MultiPoint p = new MultiPoint();
- p.addAttribute(VertexDescription.Semantics.Z);
- p.addAttribute(VertexDescription.Semantics.M);
- String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
- p);
- assertTrue(s
- .equals("{\"hasZ\":true,\"hasM\":true,\"points\":[],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
-
- p.add(10.0, 20.0, 30.0);
- p.add(20.0, 40.0, 60.0);
- s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
- assertTrue(s
- .equals("{\"hasZ\":true,\"hasM\":true,\"points\":[[10.0,20.0,30.0,null],[20.0,40.0,60.0,null]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
- }
- {
- String points = "{\"hasM\" : false, \"hasZ\" : true, \"uncle remus\" : null, \"points\" : [ [0,0,1], [0.0,10.0,1], [10.0,10.0,1], [10.0,0.0,1, 6666] ],\"spatialReference\" : {\"wkid\" : 4326}}";
- MapGeometry mp = GeometryEngine.jsonToGeometry(factory
- .createJsonParser(points));
- MultiPoint multipoint = (MultiPoint) mp.getGeometry();
- assertTrue(multipoint.getPointCount() == 4);
- Point2D point2d;
- point2d = multipoint.getXY(0);
- assertTrue(point2d.x == 0.0 && point2d.y == 0.0);
- point2d = multipoint.getXY(1);
- assertTrue(point2d.x == 0.0 && point2d.y == 10.0);
- point2d = multipoint.getXY(2);
- assertTrue(point2d.x == 10.0 && point2d.y == 10.0);
- point2d = multipoint.getXY(3);
- assertTrue(point2d.x == 10.0 && point2d.y == 0.0);
- assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
- assertTrue(!multipoint.hasAttribute(VertexDescription.Semantics.M));
- double z = multipoint.getAttributeAsDbl(
- VertexDescription.Semantics.Z, 0, 0);
- assertTrue(z == 1);
- SpatialReference spatial_reference = mp.getSpatialReference();
- assertTrue(spatial_reference.getID() == 4326);
- }
-
- return bAnswer;
- }
-
- boolean testPolyline() throws JsonParseException, IOException {
- boolean bAnswer = true;
-
- Polyline polyline = new Polyline();
- polyline.startPath(-97.06138, 32.837);
- polyline.lineTo(-97.06133, 32.836);
- polyline.lineTo(-97.06124, 32.834);
- polyline.lineTo(-97.06127, 32.832);
-
- polyline.startPath(-97.06326, 32.759);
- polyline.lineTo(-97.06298, 32.755);
-
- {
- JsonParser polylinePathsWgs84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, polyline));
- MapGeometry mPolylineWGS84MP = GeometryEngine
- .jsonToGeometry(polylinePathsWgs84Parser);
-
- assertTrue(polyline.getPointCount() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPointCount());
- assertTrue(polyline.getPoint(0).getX() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(0).getX());
- assertTrue(polyline.getPoint(0).getY() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(0).getY());
-
- assertTrue(polyline.getPathCount() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPathCount());
- assertTrue(polyline.getSegmentCount() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getSegmentCount());
- assertTrue(polyline.getSegmentCount(0) == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getSegmentCount(0));
- assertTrue(polyline.getSegmentCount(1) == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getSegmentCount(1));
-
- int lastIndex = polyline.getPointCount() - 1;
- assertTrue(polyline.getPoint(lastIndex).getX() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(lastIndex).getX());
- assertTrue(polyline.getPoint(lastIndex).getY() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(lastIndex).getY());
-
- assertTrue(spatialReferenceWGS84.getID() == mPolylineWGS84MP
- .getSpatialReference().getID());
-
- if (!checkResultSpatialRef(mPolylineWGS84MP, 4326, 0)) {
- bAnswer = false;
- }
- }
-
- {
- Polyline p = new Polyline();
- p.addAttribute(VertexDescription.Semantics.Z);
- p.addAttribute(VertexDescription.Semantics.M);
- String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
- p);
- assertTrue(s
- .equals("{\"hasZ\":true,\"hasM\":true,\"paths\":[],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
-
- p.startPath(0, 0);
- p.lineTo(0, 1);
- p.startPath(2, 2);
- p.lineTo(3, 3);
-
- p.setAttribute(VertexDescription.Semantics.Z, 0, 0, 3);
- p.setAttribute(VertexDescription.Semantics.M, 1, 0, 5);
- s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
- assertTrue(s
- .equals("{\"hasZ\":true,\"hasM\":true,\"paths\":[[[0.0,0.0,3.0,null],[0.0,1.0,0.0,5.0]],[[2.0,2.0,0.0,null],[3.0,3.0,0.0,null]]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
- }
-
- {
- String paths = "{\"hasZ\" : true, \"paths\" : [ [ [0.0, 0.0,3], [0, 10.0,3], [10.0, 10.0,3, 6666], [10.0, 0.0,3, 6666] ], [ [1.0, 1,3], [1.0, 9.0,3], [9.0, 9.0,3], [1.0, 9.0,3] ] ], \"spatialReference\" : {\"wkid\" : 4326}, \"hasM\" : false}";
- MapGeometry mapGeometry = GeometryEngine.jsonToGeometry(factory
- .createJsonParser(paths));
- Polyline p = (Polyline) mapGeometry.getGeometry();
- assertTrue(p.getPathCount() == 2);
- @SuppressWarnings("unused")
- int count = p.getPathCount();
- assertTrue(p.getPointCount() == 8);
- assertTrue(p.hasAttribute(VertexDescription.Semantics.Z));
- assertTrue(!p.hasAttribute(VertexDescription.Semantics.M));
- double z = p.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0);
- assertTrue(z == 3);
- double length = p.calculateLength2D();
- assertTrue(Math.abs(length - 54.0) <= 0.001);
- SpatialReference spatial_reference = mapGeometry
- .getSpatialReference();
- assertTrue(spatial_reference.getID() == 4326);
- }
-
- return bAnswer;
- }
-
- boolean testPolygon() throws JsonParseException, IOException {
- boolean bAnswer = true;
-
- Polygon polygon = new Polygon();
- polygon.startPath(-97.06138, 32.837);
- polygon.lineTo(-97.06133, 32.836);
- polygon.lineTo(-97.06124, 32.834);
- polygon.lineTo(-97.06127, 32.832);
-
- polygon.startPath(-97.06326, 32.759);
- polygon.lineTo(-97.06298, 32.755);
-
- {
- JsonParser polygonPathsWgs84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, polygon));
- MapGeometry mPolygonWGS84MP = GeometryEngine
- .jsonToGeometry(polygonPathsWgs84Parser);
-
- assertTrue(polygon.getPointCount() + 1 == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPointCount());
- assertTrue(polygon.getPoint(0).getX() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(0).getX());
- assertTrue(polygon.getPoint(0).getY() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(0).getY());
-
- assertTrue(polygon.getPathCount() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPathCount());
- assertTrue(polygon.getSegmentCount() + 1 == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getSegmentCount());
- assertTrue(polygon.getSegmentCount(0) == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getSegmentCount(0));
- assertTrue(polygon.getSegmentCount(1) + 1 == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getSegmentCount(1));
-
- int lastIndex = polygon.getPointCount() - 1;
- assertTrue(polygon.getPoint(lastIndex).getX() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(lastIndex).getX());
- assertTrue(polygon.getPoint(lastIndex).getY() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(lastIndex).getY());
-
- assertTrue(spatialReferenceWGS84.getID() == mPolygonWGS84MP
- .getSpatialReference().getID());
-
- if (!checkResultSpatialRef(mPolygonWGS84MP, 4326, 0)) {
- bAnswer = false;
- }
- }
-
- {
- Polygon p = new Polygon();
- p.addAttribute(VertexDescription.Semantics.Z);
- p.addAttribute(VertexDescription.Semantics.M);
- String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
- p);
- assertTrue(s
- .equals("{\"hasZ\":true,\"hasM\":true,\"rings\":[],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
-
- p.startPath(0, 0);
- p.lineTo(0, 1);
- p.lineTo(4, 4);
- p.startPath(2, 2);
- p.lineTo(3, 3);
- p.lineTo(7, 8);
-
- p.setAttribute(VertexDescription.Semantics.Z, 0, 0, 3);
- p.setAttribute(VertexDescription.Semantics.M, 1, 0, 7);
- p.setAttribute(VertexDescription.Semantics.M, 2, 0, 5);
- p.setAttribute(VertexDescription.Semantics.M, 5, 0, 5);
- s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
- assertTrue(s
- .equals("{\"hasZ\":true,\"hasM\":true,\"rings\":[[[0.0,0.0,3.0,null],[0.0,1.0,0.0,7.0],[4.0,4.0,0.0,5.0],[0.0,0.0,3.0,null]],[[2.0,2.0,0.0,null],[3.0,3.0,0.0,null],[7.0,8.0,0.0,5.0],[2.0,2.0,0.0,null]]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
- }
-
- {
- // Test Import Polygon from Polygon
- String rings = "{\"hasZ\": true, \"rings\" : [ [ [0,0, 5], [0.0, 10.0, 5], [10.0,10.0, 5, 66666], [10.0,0.0, 5] ], [ [12, 12] ], [ [13 , 17], [13 , 17] ], [ [1.0, 1.0, 5, 66666], [9.0,1.0, 5], [9.0,9.0, 5], [1.0,9.0, 5], [1.0, 1.0, 5] ] ] }";
- MapGeometry mapGeometry = GeometryEngine.jsonToGeometry(factory
- .createJsonParser(rings));
- Polygon p = (Polygon) mapGeometry.getGeometry();
- @SuppressWarnings("unused")
- double area = p.calculateArea2D();
- @SuppressWarnings("unused")
- double length = p.calculateLength2D();
- assertTrue(p.getPathCount() == 4);
- int count = p.getPointCount();
- assertTrue(count == 15);
- assertTrue(p.hasAttribute(VertexDescription.Semantics.Z));
- assertTrue(!p.hasAttribute(VertexDescription.Semantics.M));
- }
-
- return bAnswer;
- }
-
- boolean testEnvelope() throws JsonParseException, IOException {
- boolean bAnswer = true;
-
- Envelope envelope = new Envelope();
- envelope.setCoords(-109.55, 25.76, -86.39, 49.94);
-
- {
- JsonParser envelopeWGS84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, envelope));
- MapGeometry envelopeWGS84MP = GeometryEngine
- .jsonToGeometry(envelopeWGS84Parser);
- assertTrue(envelope.isEmpty() == envelopeWGS84MP.getGeometry()
- .isEmpty());
- assertTrue(envelope.getXMax() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getXMax());
- assertTrue(envelope.getYMax() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getYMax());
- assertTrue(envelope.getXMin() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getXMin());
- assertTrue(envelope.getYMin() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getYMin());
- assertTrue(spatialReferenceWGS84.getID() == envelopeWGS84MP
- .getSpatialReference().getID());
- if (!checkResultSpatialRef(envelopeWGS84MP, 4326, 0)) {
- bAnswer = false;
- }
- }
-
- {// export
- Envelope e = new Envelope();
- e.addAttribute(VertexDescription.Semantics.Z);
- e.addAttribute(VertexDescription.Semantics.M);
- String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
- e);
- assertTrue(s
- .equals("{\"xmin\":null,\"ymin\":null,\"xmax\":null,\"ymax\":null,\"zmin\":null,\"zmax\":null,\"mmin\":null,\"mmax\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
-
- e.setCoords(0, 1, 2, 3);
-
- Envelope1D z = new Envelope1D();
- Envelope1D m = new Envelope1D();
- z.setCoords(5, 7);
- m.setCoords(11, 13);
-
- e.setInterval(VertexDescription.Semantics.Z, 0, z);
- e.setInterval(VertexDescription.Semantics.M, 0, m);
- s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, e);
- assertTrue(s
- .equals("{\"xmin\":0.0,\"ymin\":1.0,\"xmax\":2.0,\"ymax\":3.0,\"zmin\":5.0,\"zmax\":7.0,\"mmin\":11.0,\"mmax\":13.0,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
- }
-
- {// import
- String s = "{\"xmin\":0.0,\"ymin\":1.0,\"xmax\":2.0,\"ymax\":3.0,\"zmin\":5.0,\"zmax\":7.0,\"mmin\":11.0,\"mmax\":13.0,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}";
- JsonParser parser = factory.createJsonParser(s);
- MapGeometry map_env = GeometryEngine.jsonToGeometry(parser);
- Envelope env = (Envelope) map_env.getGeometry();
- Envelope1D z = env.queryInterval(VertexDescription.Semantics.Z, 0);
- Envelope1D m = env.queryInterval(VertexDescription.Semantics.M, 0);
- assertTrue(z.vmin == 5.0);
- assertTrue(z.vmax == 7.0);
- assertTrue(m.vmin == 11.0);
- assertTrue(m.vmax == 13.0);
- }
-
- {
- String s = "{ \"zmin\" : 33, \"xmin\" : -109.55, \"zmax\" : 53, \"ymin\" : 25.76, \"xmax\" : -86.39, \"ymax\" : 49.94, \"mmax\" : 13}";
- JsonParser parser = factory.createJsonParser(s);
- MapGeometry map_env = GeometryEngine.jsonToGeometry(parser);
- Envelope env = (Envelope) map_env.getGeometry();
- Envelope2D e = new Envelope2D();
- env.queryEnvelope2D(e);
- assertTrue(e.xmin == -109.55 && e.ymin == 25.76 && e.xmax == -86.39
- && e.ymax == 49.94);
-
- Envelope1D e1D;
- assertTrue(env.hasAttribute(VertexDescription.Semantics.Z));
- e1D = env.queryInterval(VertexDescription.Semantics.Z, 0);
- assertTrue(e1D.vmin == 33 && e1D.vmax == 53);
-
- assertTrue(!env.hasAttribute(VertexDescription.Semantics.M));
- }
-
- return bAnswer;
- }
-
- boolean testCR181369() throws JsonParseException, IOException {
- // CR181369
- boolean bAnswer = true;
-
- String jsonStringPointAndWKT = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkt\" : \"PROJCS[\\\"NAD83_UTM_zone_15N\\\",GEOGCS[\\\"GCS_North_American_1983\\\",DATUM[\\\"D_North_American_1983\\\",SPHEROID[\\\"GRS_1980\\\",6378137.0,298.257222101]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Transverse_Mercator\\\"],PARAMETER[\\\"false_easting\\\",500000.0],PARAMETER[\\\"false_northing\\\",0.0],PARAMETER[\\\"central_meridian\\\",-93.0],PARAMETER[\\\"scale_factor\\\",0.9996],PARAMETER[\\\"latitude_of_origin\\\",0.0],UNIT[\\\"Meter\\\",1.0]]\"} }";
- JsonParser jsonParserPointAndWKT = factory
- .createJsonParser(jsonStringPointAndWKT);
- MapGeometry mapGeom2 = GeometryEngine
- .jsonToGeometry(jsonParserPointAndWKT);
- String jsonStringPointAndWKT2 = GeometryEngine.geometryToJson(
- mapGeom2.getSpatialReference(), mapGeom2.getGeometry());
- JsonParser jsonParserPointAndWKT2 = factory
- .createJsonParser(jsonStringPointAndWKT2);
- MapGeometry mapGeom3 = GeometryEngine
- .jsonToGeometry(jsonParserPointAndWKT2);
- assertTrue(((Point) mapGeom2.getGeometry()).getX() == ((Point) mapGeom3
- .getGeometry()).getX());
- assertTrue(((Point) mapGeom2.getGeometry()).getY() == ((Point) mapGeom3
- .getGeometry()).getY());
-
- String s1 = mapGeom2.getSpatialReference().getText();
- String s2 = mapGeom3.getSpatialReference().getText();
- assertTrue(s1.equals(s2));
-
- int id2 = mapGeom2.getSpatialReference().getID();
- int id3 = mapGeom3.getSpatialReference().getID();
- assertTrue(id2 == id3);
- if (!checkResultSpatialRef(mapGeom3, mapGeom2.getSpatialReference()
- .getID(), 0)) {
- bAnswer = false;
- }
- return bAnswer;
- }
-
- boolean checkResultSpatialRef(MapGeometry mapGeometry, int expectWki1,
- int expectWki2) {
- SpatialReference sr = mapGeometry.getSpatialReference();
- String Wkt = sr.getText();
- int wki1 = sr.getLatestID();
- if (!(wki1 == expectWki1 || wki1 == expectWki2))
- return false;
- if (!(Wkt != null && Wkt.length() > 0))
- return false;
- System.out.println("WKT1: " + Wkt);
- SpatialReference sr2 = SpatialReference.create(Wkt);
- int wki2 = sr2.getID();
- if (expectWki2 > 0) {
- if (!(wki2 == expectWki1 || wki2 == expectWki2))
- return false;
- } else {
- if (!(wki2 == expectWki1))
- return false;
- }
- return true;
- }
-}
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+
+public class TestGeomToJSonExportSRFromWkiOrWkt_CR181369 extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ JsonFactory factory = new JsonFactory();
+ SpatialReference spatialReferenceWebMerc1 = SpatialReference.create(102100);
+ SpatialReference spatialReferenceWebMerc2 = SpatialReference
+ .create(spatialReferenceWebMerc1.getLatestID());
+ SpatialReference spatialReferenceWGS84 = SpatialReference.create(4326);
+
+ @Test
+ public void testLocalExport()
+ throws JsonParseException, IOException {
+ String s = OperatorExportToJson.local().execute(null, new Point(1000000.2, 2000000.3));
+ //assertTrue(s.contains("."));
+ //assertFalse(s.contains(","));
+ Polyline line = new Polyline();
+ line.startPath(1.1, 2.2);
+ line.lineTo(2.3, 4.5);
+ String s1 = OperatorExportToJson.local().execute(null, line);
+ assertTrue(s.contains("."));
+ }
+
+ boolean testPoint() throws JsonParseException, IOException {
+ boolean bAnswer = true;
+ Point point1 = new Point(10.0, 20.0);
+ Point pointEmpty = new Point();
+ {
+ JsonParser pointWebMerc1Parser = factory
+ .createParser(GeometryEngine.geometryToJson(
+ spatialReferenceWebMerc1, point1));
+ MapGeometry pointWebMerc1MP = GeometryEngine
+ .jsonToGeometry(pointWebMerc1Parser);
+ assertTrue(point1.getX() == ((Point) pointWebMerc1MP.getGeometry())
+ .getX());
+ assertTrue(point1.getY() == ((Point) pointWebMerc1MP.getGeometry())
+ .getY());
+ assertTrue(spatialReferenceWebMerc1.getID() == pointWebMerc1MP
+ .getSpatialReference().getID()
+ || pointWebMerc1MP.getSpatialReference().getID() == 3857);
+
+ if (!checkResultSpatialRef(pointWebMerc1MP, 102100, 3857)) {
+ bAnswer = false;
+ }
+
+ pointWebMerc1Parser = factory.createParser(GeometryEngine
+ .geometryToJson(null, point1));
+ pointWebMerc1MP = GeometryEngine
+ .jsonToGeometry(pointWebMerc1Parser);
+ assertTrue(null == pointWebMerc1MP.getSpatialReference());
+
+ if (pointWebMerc1MP.getSpatialReference() != null) {
+ if (!checkResultSpatialRef(pointWebMerc1MP, 102100, 3857)) {
+ bAnswer = false;
+ }
+ }
+
+ String pointEmptyString = GeometryEngine.geometryToJson(
+ spatialReferenceWebMerc1, pointEmpty);
+ pointWebMerc1Parser = factory.createParser(pointEmptyString);
+ }
+
+ JsonParser pointWebMerc2Parser = factory
+ .createParser(GeometryEngine.geometryToJson(
+ spatialReferenceWebMerc2, point1));
+ MapGeometry pointWebMerc2MP = GeometryEngine
+ .jsonToGeometry(pointWebMerc2Parser);
+ assertTrue(point1.getX() == ((Point) pointWebMerc2MP.getGeometry())
+ .getX());
+ assertTrue(point1.getY() == ((Point) pointWebMerc2MP.getGeometry())
+ .getY());
+ assertTrue(spatialReferenceWebMerc2.getLatestID() == pointWebMerc2MP
+ .getSpatialReference().getLatestID());
+ if (!checkResultSpatialRef(pointWebMerc2MP,
+ spatialReferenceWebMerc2.getLatestID(), 0)) {
+ bAnswer = false;
+ }
+
+ {
+ JsonParser pointWgs84Parser = factory
+ .createParser(GeometryEngine.geometryToJson(
+ spatialReferenceWGS84, point1));
+ MapGeometry pointWgs84MP = GeometryEngine
+ .jsonToGeometry(pointWgs84Parser);
+ assertTrue(point1.getX() == ((Point) pointWgs84MP.getGeometry())
+ .getX());
+ assertTrue(point1.getY() == ((Point) pointWgs84MP.getGeometry())
+ .getY());
+ assertTrue(spatialReferenceWGS84.getID() == pointWgs84MP
+ .getSpatialReference().getID());
+ if (!checkResultSpatialRef(pointWgs84MP, 4326, 0)) {
+ bAnswer = false;
+ }
+ }
+
+ {
+ Point p = new Point();
+ String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
+ p);
+ assertTrue(s
+ .equals("{\"x\":null,\"y\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+
+ p.addAttribute(VertexDescription.Semantics.Z);
+ p.addAttribute(VertexDescription.Semantics.M);
+ s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
+ assertTrue(s
+ .equals("{\"x\":null,\"y\":null,\"z\":null,\"m\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+
+ }
+
+ {
+ Point p = new Point(10.0, 20.0, 30.0);
+ p.addAttribute(VertexDescription.Semantics.M);
+ String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
+ p);
+ assertTrue(s
+ .equals("{\"x\":10,\"y\":20,\"z\":30,\"m\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+ }
+
+ {// import
+ String s = "{\"x\":0.0,\"y\":1.0,\"z\":5.0,\"m\":11.0,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}";
+ JsonParser parser = factory.createParser(s);
+ MapGeometry map_pt = GeometryEngine.jsonToGeometry(parser);
+ Point pt = (Point) map_pt.getGeometry();
+ assertTrue(pt.getX() == 0.0);
+ assertTrue(pt.getY() == 1.0);
+ assertTrue(pt.getZ() == 5.0);
+ assertTrue(pt.getM() == 11.0);
+ }
+
+ {
+ String s = "{\"x\" : 5.0, \"y\" : null, \"spatialReference\" : {\"wkid\" : 4326}} ";
+ JsonParser parser = factory.createParser(s);
+ MapGeometry map_pt = GeometryEngine.jsonToGeometry(parser);
+ Point pt = (Point) map_pt.getGeometry();
+ assertTrue(pt.isEmpty());
+ SpatialReference spatial_reference = map_pt.getSpatialReference();
+ assertTrue(spatial_reference.getID() == 4326);
+ }
+
+ return bAnswer;
+ }
+
+ boolean testMultiPoint() throws JsonParseException, IOException {
+ boolean bAnswer = true;
+
+ MultiPoint multiPoint1 = new MultiPoint();
+ multiPoint1.add(-97.06138, 32.837);
+ multiPoint1.add(-97.06133, 32.836);
+ multiPoint1.add(-97.06124, 32.834);
+ multiPoint1.add(-97.06127, 32.832);
+
+ {
+ String s = GeometryEngine.geometryToJson(spatialReferenceWGS84,
+ multiPoint1);
+ JsonParser mPointWgs84Parser = factory.createParser(s);
+ MapGeometry mPointWgs84MP = GeometryEngine
+ .jsonToGeometry(mPointWgs84Parser);
+ assertTrue(multiPoint1.getPointCount() == ((MultiPoint) mPointWgs84MP
+ .getGeometry()).getPointCount());
+ assertTrue(multiPoint1.getPoint(0).getX() == ((MultiPoint) mPointWgs84MP
+ .getGeometry()).getPoint(0).getX());
+ assertTrue(multiPoint1.getPoint(0).getY() == ((MultiPoint) mPointWgs84MP
+ .getGeometry()).getPoint(0).getY());
+ int lastIndex = multiPoint1.getPointCount() - 1;
+ assertTrue(multiPoint1.getPoint(lastIndex).getX() == ((MultiPoint) mPointWgs84MP
+ .getGeometry()).getPoint(lastIndex).getX());
+ assertTrue(multiPoint1.getPoint(lastIndex).getY() == ((MultiPoint) mPointWgs84MP
+ .getGeometry()).getPoint(lastIndex).getY());
+
+ assertTrue(spatialReferenceWGS84.getID() == mPointWgs84MP
+ .getSpatialReference().getID());
+ if (!checkResultSpatialRef(mPointWgs84MP, 4326, 0)) {
+ bAnswer = false;
+ }
+
+ }
+
+ {
+ MultiPoint p = new MultiPoint();
+ p.addAttribute(VertexDescription.Semantics.Z);
+ p.addAttribute(VertexDescription.Semantics.M);
+ String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
+ p);
+ assertTrue(s
+ .equals("{\"hasZ\":true,\"hasM\":true,\"points\":[],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+
+ p.add(10.0, 20.0, 30.0);
+ p.add(20.0, 40.0, 60.0);
+ s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
+ assertTrue(s
+ .equals("{\"hasZ\":true,\"hasM\":true,\"points\":[[10,20,30,null],[20,40,60,null]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+ }
+ {
+ String points = "{\"hasM\" : false, \"hasZ\" : true, \"uncle remus\" : null, \"points\" : [ [0,0,1], [0.0,10.0,1], [10.0,10.0,1], [10.0,0.0,1, 6666] ],\"spatialReference\" : {\"wkid\" : 4326}}";
+ MapGeometry mp = GeometryEngine.jsonToGeometry(factory
+ .createParser(points));
+ MultiPoint multipoint = (MultiPoint) mp.getGeometry();
+ assertTrue(multipoint.getPointCount() == 4);
+ Point2D point2d;
+ point2d = multipoint.getXY(0);
+ assertTrue(point2d.x == 0.0 && point2d.y == 0.0);
+ point2d = multipoint.getXY(1);
+ assertTrue(point2d.x == 0.0 && point2d.y == 10.0);
+ point2d = multipoint.getXY(2);
+ assertTrue(point2d.x == 10.0 && point2d.y == 10.0);
+ point2d = multipoint.getXY(3);
+ assertTrue(point2d.x == 10.0 && point2d.y == 0.0);
+ assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(!multipoint.hasAttribute(VertexDescription.Semantics.M));
+ double z = multipoint.getAttributeAsDbl(
+ VertexDescription.Semantics.Z, 0, 0);
+ assertTrue(z == 1);
+ SpatialReference spatial_reference = mp.getSpatialReference();
+ assertTrue(spatial_reference.getID() == 4326);
+ }
+
+ return bAnswer;
+ }
+
+ boolean testPolyline() throws JsonParseException, IOException {
+ boolean bAnswer = true;
+
+ Polyline polyline = new Polyline();
+ polyline.startPath(-97.06138, 32.837);
+ polyline.lineTo(-97.06133, 32.836);
+ polyline.lineTo(-97.06124, 32.834);
+ polyline.lineTo(-97.06127, 32.832);
+
+ polyline.startPath(-97.06326, 32.759);
+ polyline.lineTo(-97.06298, 32.755);
+
+ {
+ JsonParser polylinePathsWgs84Parser = factory
+ .createParser(GeometryEngine.geometryToJson(
+ spatialReferenceWGS84, polyline));
+ MapGeometry mPolylineWGS84MP = GeometryEngine
+ .jsonToGeometry(polylinePathsWgs84Parser);
+
+ assertTrue(polyline.getPointCount() == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getPointCount());
+ assertTrue(polyline.getPoint(0).getX() == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getPoint(0).getX());
+ assertTrue(polyline.getPoint(0).getY() == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getPoint(0).getY());
+
+ assertTrue(polyline.getPathCount() == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getPathCount());
+ assertTrue(polyline.getSegmentCount() == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getSegmentCount());
+ assertTrue(polyline.getSegmentCount(0) == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getSegmentCount(0));
+ assertTrue(polyline.getSegmentCount(1) == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getSegmentCount(1));
+
+ int lastIndex = polyline.getPointCount() - 1;
+ assertTrue(polyline.getPoint(lastIndex).getX() == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getPoint(lastIndex).getX());
+ assertTrue(polyline.getPoint(lastIndex).getY() == ((Polyline) mPolylineWGS84MP
+ .getGeometry()).getPoint(lastIndex).getY());
+
+ assertTrue(spatialReferenceWGS84.getID() == mPolylineWGS84MP
+ .getSpatialReference().getID());
+
+ if (!checkResultSpatialRef(mPolylineWGS84MP, 4326, 0)) {
+ bAnswer = false;
+ }
+ }
+
+ {
+ Polyline p = new Polyline();
+ p.addAttribute(VertexDescription.Semantics.Z);
+ p.addAttribute(VertexDescription.Semantics.M);
+ String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
+ p);
+ assertTrue(s
+ .equals("{\"hasZ\":true,\"hasM\":true,\"paths\":[],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+
+ p.startPath(0, 0);
+ p.lineTo(0, 1);
+ p.startPath(2, 2);
+ p.lineTo(3, 3);
+
+ p.setAttribute(VertexDescription.Semantics.Z, 0, 0, 3);
+ p.setAttribute(VertexDescription.Semantics.M, 1, 0, 5);
+ s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
+ assertTrue(s
+ .equals("{\"hasZ\":true,\"hasM\":true,\"paths\":[[[0,0,3,null],[0,1,0,5]],[[2,2,0,null],[3,3,0,null]]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+ }
+
+ {
+ String paths = "{\"hasZ\" : true, \"paths\" : [ [ [0.0, 0.0,3], [0, 10.0,3], [10.0, 10.0,3, 6666], [10.0, 0.0,3, 6666] ], [ [1.0, 1,3], [1.0, 9.0,3], [9.0, 9.0,3], [1.0, 9.0,3] ] ], \"spatialReference\" : {\"wkid\" : 4326}, \"hasM\" : false}";
+ MapGeometry mapGeometry = GeometryEngine.jsonToGeometry(factory
+ .createParser(paths));
+ Polyline p = (Polyline) mapGeometry.getGeometry();
+ assertTrue(p.getPathCount() == 2);
+ @SuppressWarnings("unused")
+ int count = p.getPathCount();
+ assertTrue(p.getPointCount() == 8);
+ assertTrue(p.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(!p.hasAttribute(VertexDescription.Semantics.M));
+ double z = p.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0);
+ assertTrue(z == 3);
+ double length = p.calculateLength2D();
+ assertTrue(Math.abs(length - 54.0) <= 0.001);
+ SpatialReference spatial_reference = mapGeometry
+ .getSpatialReference();
+ assertTrue(spatial_reference.getID() == 4326);
+ }
+
+ return bAnswer;
+ }
+
+ boolean testPolygon() throws JsonParseException, IOException {
+ boolean bAnswer = true;
+
+ Polygon polygon = new Polygon();
+ polygon.startPath(-97.06138, 32.837);
+ polygon.lineTo(-97.06133, 32.836);
+ polygon.lineTo(-97.06124, 32.834);
+ polygon.lineTo(-97.06127, 32.832);
+
+ polygon.startPath(-97.06326, 32.759);
+ polygon.lineTo(-97.06298, 32.755);
+
+ {
+ JsonParser polygonPathsWgs84Parser = factory
+ .createParser(GeometryEngine.geometryToJson(
+ spatialReferenceWGS84, polygon));
+ MapGeometry mPolygonWGS84MP = GeometryEngine
+ .jsonToGeometry(polygonPathsWgs84Parser);
+
+ assertTrue(polygon.getPointCount() + 1 == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getPointCount());
+ assertTrue(polygon.getPoint(0).getX() == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getPoint(0).getX());
+ assertTrue(polygon.getPoint(0).getY() == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getPoint(0).getY());
+
+ assertTrue(polygon.getPathCount() == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getPathCount());
+ assertTrue(polygon.getSegmentCount() + 1 == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getSegmentCount());
+ assertTrue(polygon.getSegmentCount(0) == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getSegmentCount(0));
+ assertTrue(polygon.getSegmentCount(1) + 1 == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getSegmentCount(1));
+
+ int lastIndex = polygon.getPointCount() - 1;
+ assertTrue(polygon.getPoint(lastIndex).getX() == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getPoint(lastIndex).getX());
+ assertTrue(polygon.getPoint(lastIndex).getY() == ((Polygon) mPolygonWGS84MP
+ .getGeometry()).getPoint(lastIndex).getY());
+
+ assertTrue(spatialReferenceWGS84.getID() == mPolygonWGS84MP
+ .getSpatialReference().getID());
+
+ if (!checkResultSpatialRef(mPolygonWGS84MP, 4326, 0)) {
+ bAnswer = false;
+ }
+ }
+
+ {
+ Polygon p = new Polygon();
+ p.addAttribute(VertexDescription.Semantics.Z);
+ p.addAttribute(VertexDescription.Semantics.M);
+ String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
+ p);
+ assertTrue(s
+ .equals("{\"hasZ\":true,\"hasM\":true,\"rings\":[],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+
+ p.startPath(0, 0);
+ p.lineTo(0, 1);
+ p.lineTo(4, 4);
+ p.startPath(2, 2);
+ p.lineTo(3, 3);
+ p.lineTo(7, 8);
+
+ p.setAttribute(VertexDescription.Semantics.Z, 0, 0, 3);
+ p.setAttribute(VertexDescription.Semantics.M, 1, 0, 7);
+ p.setAttribute(VertexDescription.Semantics.M, 2, 0, 5);
+ p.setAttribute(VertexDescription.Semantics.M, 5, 0, 5);
+ s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, p);
+ assertTrue(s
+ .equals("{\"hasZ\":true,\"hasM\":true,\"rings\":[[[0,0,3,null],[0,1,0,7],[4,4,0,5],[0,0,3,null]],[[2,2,0,null],[3,3,0,null],[7,8,0,5],[2,2,0,null]]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+ }
+
+ {
+ // Test Import Polygon from Polygon
+ String rings = "{\"hasZ\": true, \"rings\" : [ [ [0,0, 5], [0.0, 10.0, 5], [10.0,10.0, 5, 66666], [10.0,0.0, 5] ], [ [12, 12] ], [ [13 , 17], [13 , 17] ], [ [1.0, 1.0, 5, 66666], [9.0,1.0, 5], [9.0,9.0, 5], [1.0,9.0, 5], [1.0, 1.0, 5] ] ] }";
+ MapGeometry mapGeometry = GeometryEngine.jsonToGeometry(factory
+ .createParser(rings));
+ Polygon p = (Polygon) mapGeometry.getGeometry();
+ @SuppressWarnings("unused")
+ double area = p.calculateArea2D();
+ @SuppressWarnings("unused")
+ double length = p.calculateLength2D();
+ assertTrue(p.getPathCount() == 4);
+ int count = p.getPointCount();
+ assertTrue(count == 15);
+ assertTrue(p.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(!p.hasAttribute(VertexDescription.Semantics.M));
+ }
+
+ return bAnswer;
+ }
+
+ boolean testEnvelope() throws JsonParseException, IOException {
+ boolean bAnswer = true;
+
+ Envelope envelope = new Envelope();
+ envelope.setCoords(-109.55, 25.76, -86.39, 49.94);
+
+ {
+ JsonParser envelopeWGS84Parser = factory
+ .createParser(GeometryEngine.geometryToJson(
+ spatialReferenceWGS84, envelope));
+ MapGeometry envelopeWGS84MP = GeometryEngine
+ .jsonToGeometry(envelopeWGS84Parser);
+ assertTrue(envelope.isEmpty() == envelopeWGS84MP.getGeometry()
+ .isEmpty());
+ assertTrue(envelope.getXMax() == ((Envelope) envelopeWGS84MP
+ .getGeometry()).getXMax());
+ assertTrue(envelope.getYMax() == ((Envelope) envelopeWGS84MP
+ .getGeometry()).getYMax());
+ assertTrue(envelope.getXMin() == ((Envelope) envelopeWGS84MP
+ .getGeometry()).getXMin());
+ assertTrue(envelope.getYMin() == ((Envelope) envelopeWGS84MP
+ .getGeometry()).getYMin());
+ assertTrue(spatialReferenceWGS84.getID() == envelopeWGS84MP
+ .getSpatialReference().getID());
+ if (!checkResultSpatialRef(envelopeWGS84MP, 4326, 0)) {
+ bAnswer = false;
+ }
+ }
+
+ {// export
+ Envelope e = new Envelope();
+ e.addAttribute(VertexDescription.Semantics.Z);
+ e.addAttribute(VertexDescription.Semantics.M);
+ String s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1,
+ e);
+ assertTrue(s
+ .equals("{\"xmin\":null,\"ymin\":null,\"xmax\":null,\"ymax\":null,\"zmin\":null,\"zmax\":null,\"mmin\":null,\"mmax\":null,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+
+ e.setCoords(0, 1, 2, 3);
+
+ Envelope1D z = new Envelope1D();
+ Envelope1D m = new Envelope1D();
+ z.setCoords(5, 7);
+ m.setCoords(11, 13);
+
+ e.setInterval(VertexDescription.Semantics.Z, 0, z);
+ e.setInterval(VertexDescription.Semantics.M, 0, m);
+ s = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, e);
+ assertTrue(s
+ .equals("{\"xmin\":0,\"ymin\":1,\"xmax\":2,\"ymax\":3,\"zmin\":5,\"zmax\":7,\"mmin\":11,\"mmax\":13,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}"));
+ }
+
+ {// import
+ String s = "{\"xmin\":0.0,\"ymin\":1.0,\"xmax\":2.0,\"ymax\":3.0,\"zmin\":5.0,\"zmax\":7.0,\"mmin\":11.0,\"mmax\":13.0,\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}";
+ JsonParser parser = factory.createParser(s);
+ MapGeometry map_env = GeometryEngine.jsonToGeometry(parser);
+ Envelope env = (Envelope) map_env.getGeometry();
+ Envelope1D z = env.queryInterval(VertexDescription.Semantics.Z, 0);
+ Envelope1D m = env.queryInterval(VertexDescription.Semantics.M, 0);
+ assertTrue(z.vmin == 5.0);
+ assertTrue(z.vmax == 7.0);
+ assertTrue(m.vmin == 11.0);
+ assertTrue(m.vmax == 13.0);
+ }
+
+ {
+ String s = "{ \"zmin\" : 33, \"xmin\" : -109.55, \"zmax\" : 53, \"ymin\" : 25.76, \"xmax\" : -86.39, \"ymax\" : 49.94, \"mmax\" : 13}";
+ JsonParser parser = factory.createParser(s);
+ MapGeometry map_env = GeometryEngine.jsonToGeometry(parser);
+ Envelope env = (Envelope) map_env.getGeometry();
+ Envelope2D e = new Envelope2D();
+ env.queryEnvelope2D(e);
+ assertTrue(e.xmin == -109.55 && e.ymin == 25.76 && e.xmax == -86.39
+ && e.ymax == 49.94);
+
+ Envelope1D e1D;
+ assertTrue(env.hasAttribute(VertexDescription.Semantics.Z));
+ e1D = env.queryInterval(VertexDescription.Semantics.Z, 0);
+ assertTrue(e1D.vmin == 33 && e1D.vmax == 53);
+
+ assertTrue(!env.hasAttribute(VertexDescription.Semantics.M));
+ }
+
+ return bAnswer;
+ }
+
+ boolean testCR181369() throws JsonParseException, IOException {
+ // CR181369
+ boolean bAnswer = true;
+
+ String jsonStringPointAndWKT = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkt\" : \"PROJCS[\\\"NAD83_UTM_zone_15N\\\",GEOGCS[\\\"GCS_North_American_1983\\\",DATUM[\\\"D_North_American_1983\\\",SPHEROID[\\\"GRS_1980\\\",6378137.0,298.257222101]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Transverse_Mercator\\\"],PARAMETER[\\\"false_easting\\\",500000.0],PARAMETER[\\\"false_northing\\\",0.0],PARAMETER[\\\"central_meridian\\\",-93.0],PARAMETER[\\\"scale_factor\\\",0.9996],PARAMETER[\\\"latitude_of_origin\\\",0.0],UNIT[\\\"Meter\\\",1.0]]\"} }";
+ JsonParser jsonParserPointAndWKT = factory
+ .createParser(jsonStringPointAndWKT);
+ MapGeometry mapGeom2 = GeometryEngine
+ .jsonToGeometry(jsonParserPointAndWKT);
+ String jsonStringPointAndWKT2 = GeometryEngine.geometryToJson(
+ mapGeom2.getSpatialReference(), mapGeom2.getGeometry());
+ JsonParser jsonParserPointAndWKT2 = factory
+ .createParser(jsonStringPointAndWKT2);
+ MapGeometry mapGeom3 = GeometryEngine
+ .jsonToGeometry(jsonParserPointAndWKT2);
+ assertTrue(((Point) mapGeom2.getGeometry()).getX() == ((Point) mapGeom3
+ .getGeometry()).getX());
+ assertTrue(((Point) mapGeom2.getGeometry()).getY() == ((Point) mapGeom3
+ .getGeometry()).getY());
+
+ String s1 = mapGeom2.getSpatialReference().getText();
+ String s2 = mapGeom3.getSpatialReference().getText();
+ assertTrue(s1.equals(s2));
+
+ int id2 = mapGeom2.getSpatialReference().getID();
+ int id3 = mapGeom3.getSpatialReference().getID();
+ assertTrue(id2 == id3);
+ if (!checkResultSpatialRef(mapGeom3, mapGeom2.getSpatialReference()
+ .getID(), 0)) {
+ bAnswer = false;
+ }
+ return bAnswer;
+ }
+
+ boolean checkResultSpatialRef(MapGeometry mapGeometry, int expectWki1,
+ int expectWki2) {
+ SpatialReference sr = mapGeometry.getSpatialReference();
+ String Wkt = sr.getText();
+ int wki1 = sr.getLatestID();
+ if (!(wki1 == expectWki1 || wki1 == expectWki2))
+ return false;
+ if (!(Wkt != null && Wkt.length() > 0))
+ return false;
+ SpatialReference sr2 = SpatialReference.create(Wkt);
+ int wki2 = sr2.getID();
+ if (expectWki2 > 0) {
+ if (!(wki2 == expectWki1 || wki2 == expectWki2))
+ return false;
+ } else {
+ if (!(wki2 == expectWki1))
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestImportExport.java b/src/test/java/com/esri/core/geometry/TestImportExport.java
similarity index 59%
rename from unittest/com/esri/core/geometry/TestImportExport.java
rename to src/test/java/com/esri/core/geometry/TestImportExport.java
index 9b4f19a3..73faed01 100644
--- a/unittest/com/esri/core/geometry/TestImportExport.java
+++ b/src/test/java/com/esri/core/geometry/TestImportExport.java
@@ -1,12 +1,37 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+
import junit.framework.TestCase;
-import org.json.JSONException;
import org.junit.Test;
public class TestImportExport extends TestCase {
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -19,33 +44,26 @@ protected void tearDown() throws Exception {
@Test
public static void testImportExportShapePolygon() {
- OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToESRIShape);
- OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromESRIShape);
+ OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToESRIShape);
+ OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromESRIShape);
Polygon polygon = makePolygon();
byte[] esriShape = GeometryEngine.geometryToEsriShape(polygon);
- Geometry imported = GeometryEngine.geometryFromEsriShape(esriShape,
- Geometry.Type.Unknown);
+ Geometry imported = GeometryEngine.geometryFromEsriShape(esriShape, Geometry.Type.Unknown);
TestCommonMethods.compareGeometryContent((MultiPath) imported, polygon);
// Test Import Polygon from Polygon
ByteBuffer polygonShapeBuffer = exporterShape.execute(0, polygon);
- Geometry polygonShapeGeometry = importerShape.execute(0,
- Geometry.Type.Polygon, polygonShapeBuffer);
+ Geometry polygonShapeGeometry = importerShape.execute(0, Geometry.Type.Polygon, polygonShapeBuffer);
- TestCommonMethods.compareGeometryContent(
- (MultiPath) polygonShapeGeometry, polygon);
+ TestCommonMethods.compareGeometryContent((MultiPath) polygonShapeGeometry, polygon);
// Test Import Envelope from Polygon
- Geometry envelopeShapeGeometry = importerShape.execute(0,
- Geometry.Type.Envelope, polygonShapeBuffer);
+ Geometry envelopeShapeGeometry = importerShape.execute(0, Geometry.Type.Envelope, polygonShapeBuffer);
Envelope envelope = (Envelope) envelopeShapeGeometry;
- @SuppressWarnings("unused")
- Envelope env = new Envelope(), otherenv = new Envelope();
+ @SuppressWarnings("unused") Envelope env = new Envelope(), otherenv = new Envelope();
polygon.queryEnvelope(otherenv);
assertTrue(envelope.getXMin() == otherenv.getXMin());
assertTrue(envelope.getXMax() == otherenv.getXMax());
@@ -61,25 +79,20 @@ public static void testImportExportShapePolygon() {
@Test
public static void testImportExportShapePolyline() {
- OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToESRIShape);
- OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromESRIShape);
+ OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToESRIShape);
+ OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromESRIShape);
Polyline polyline = makePolyline();
// Test Import Polyline from Polyline
ByteBuffer polylineShapeBuffer = exporterShape.execute(0, polyline);
- Geometry polylineShapeGeometry = importerShape.execute(0,
- Geometry.Type.Polyline, polylineShapeBuffer);
+ Geometry polylineShapeGeometry = importerShape.execute(0, Geometry.Type.Polyline, polylineShapeBuffer);
// TODO test this
- TestCommonMethods.compareGeometryContent(
- (MultiPath) polylineShapeGeometry, polyline);
+ TestCommonMethods.compareGeometryContent((MultiPath) polylineShapeGeometry, polyline);
// Test Import Envelope from Polyline;
- Geometry envelopeShapeGeometry = importerShape.execute(0,
- Geometry.Type.Envelope, polylineShapeBuffer);
+ Geometry envelopeShapeGeometry = importerShape.execute(0, Geometry.Type.Envelope, polylineShapeBuffer);
Envelope envelope = (Envelope) envelopeShapeGeometry;
Envelope env = new Envelope(), otherenv = new Envelope();
@@ -92,32 +105,26 @@ public static void testImportExportShapePolyline() {
Envelope1D interval, otherinterval;
interval = envelope.queryInterval(VertexDescription.Semantics.Z, 0);
- otherinterval = polyline
- .queryInterval(VertexDescription.Semantics.Z, 0);
+ otherinterval = polyline.queryInterval(VertexDescription.Semantics.Z, 0);
assertTrue(interval.vmin == otherinterval.vmin);
assertTrue(interval.vmax == otherinterval.vmax);
}
@Test
public static void testImportExportShapeMultiPoint() {
- OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToESRIShape);
- OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromESRIShape);
+ OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToESRIShape);
+ OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromESRIShape);
MultiPoint multipoint = makeMultiPoint();
// Test Import MultiPoint from MultiPoint
ByteBuffer multipointShapeBuffer = exporterShape.execute(0, multipoint);
- MultiPoint multipointShapeGeometry = (MultiPoint) importerShape
- .execute(0, Geometry.Type.MultiPoint, multipointShapeBuffer);
+ MultiPoint multipointShapeGeometry = (MultiPoint) importerShape.execute(0, Geometry.Type.MultiPoint, multipointShapeBuffer);
- TestCommonMethods.compareGeometryContent(
- (MultiPoint) multipointShapeGeometry, multipoint);
+ TestCommonMethods.compareGeometryContent((MultiPoint) multipointShapeGeometry, multipoint);
// Test Import Envelope from MultiPoint
- Geometry envelopeShapeGeometry = importerShape.execute(0,
- Geometry.Type.Envelope, multipointShapeBuffer);
+ Geometry envelopeShapeGeometry = importerShape.execute(0, Geometry.Type.Envelope, multipointShapeBuffer);
Envelope envelope = (Envelope) envelopeShapeGeometry;
Envelope env = new Envelope(), otherenv = new Envelope();
@@ -130,32 +137,27 @@ public static void testImportExportShapeMultiPoint() {
Envelope1D interval, otherinterval;
interval = envelope.queryInterval(VertexDescription.Semantics.Z, 0);
- otherinterval = multipoint.queryInterval(VertexDescription.Semantics.Z,
- 0);
+ otherinterval = multipoint.queryInterval(VertexDescription.Semantics.Z, 0);
assertTrue(interval.vmin == otherinterval.vmin);
assertTrue(interval.vmax == otherinterval.vmax);
interval = envelope.queryInterval(VertexDescription.Semantics.ID, 0);
- otherinterval = multipoint.queryInterval(
- VertexDescription.Semantics.ID, 0);
+ otherinterval = multipoint.queryInterval(VertexDescription.Semantics.ID, 0);
assertTrue(interval.vmin == otherinterval.vmin);
assertTrue(interval.vmax == otherinterval.vmax);
}
@Test
public static void testImportExportShapePoint() {
- OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToESRIShape);
- OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromESRIShape);
+ OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToESRIShape);
+ OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromESRIShape);
// Point
Point point = makePoint();
// Test Import Point from Point
ByteBuffer pointShapeBuffer = exporterShape.execute(0, point);
- Point pointShapeGeometry = (Point) importerShape.execute(0,
- Geometry.Type.Point, pointShapeBuffer);
+ Point pointShapeGeometry = (Point) importerShape.execute(0, Geometry.Type.Point, pointShapeBuffer);
double x1 = point.getX();
double x2 = pointShapeGeometry.getX();
@@ -178,29 +180,24 @@ public static void testImportExportShapePoint() {
assertTrue(id1 == id2);
// Test Import Multipoint from Point
- MultiPoint multipointShapeGeometry = (MultiPoint) importerShape
- .execute(0, Geometry.Type.MultiPoint, pointShapeBuffer);
+ MultiPoint multipointShapeGeometry = (MultiPoint) importerShape.execute(0, Geometry.Type.MultiPoint, pointShapeBuffer);
Point point2d = multipointShapeGeometry.getPoint(0);
assertTrue(x1 == point2d.getX() && y1 == point2d.getY());
int pointCount = multipointShapeGeometry.getPointCount();
assertTrue(pointCount == 1);
- z2 = multipointShapeGeometry.getAttributeAsDbl(
- VertexDescription.Semantics.Z, 0, 0);
+ z2 = multipointShapeGeometry.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0);
assertTrue(z1 == z2);
- m2 = multipointShapeGeometry.getAttributeAsDbl(
- VertexDescription.Semantics.M, 0, 0);
+ m2 = multipointShapeGeometry.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0);
assertTrue(m1 == m2);
- id2 = multipointShapeGeometry.getAttributeAsInt(
- VertexDescription.Semantics.ID, 0, 0);
+ id2 = multipointShapeGeometry.getAttributeAsInt(VertexDescription.Semantics.ID, 0, 0);
assertTrue(id1 == id2);
// Test Import Envelope from Point
- Geometry envelopeShapeGeometry = importerShape.execute(0,
- Geometry.Type.Envelope, pointShapeBuffer);
+ Geometry envelopeShapeGeometry = importerShape.execute(0, Geometry.Type.Envelope, pointShapeBuffer);
Envelope envelope = (Envelope) envelopeShapeGeometry;
Envelope env = new Envelope(), otherenv = new Envelope();
@@ -225,17 +222,14 @@ public static void testImportExportShapePoint() {
@Test
public static void testImportExportShapeEnvelope() {
- OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToESRIShape);
- OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromESRIShape);
+ OperatorExportToESRIShape exporterShape = (OperatorExportToESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToESRIShape);
+ OperatorImportFromESRIShape importerShape = (OperatorImportFromESRIShape) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromESRIShape);
// Test Export Envelope to Polygon
Envelope envelope = makeEnvelope();
ByteBuffer polygonShapeBuffer = exporterShape.execute(0, envelope);
- Polygon polygon = (Polygon) importerShape.execute(0,
- Geometry.Type.Polygon, polygonShapeBuffer);
+ Polygon polygon = (Polygon) importerShape.execute(0, Geometry.Type.Polygon, polygonShapeBuffer);
int pointCount = polygon.getPointCount();
assertTrue(pointCount == 4);
@@ -245,26 +239,21 @@ public static void testImportExportShapeEnvelope() {
// interval = envelope.queryInterval(VertexDescription.Semantics.Z, 0);
Point point3d;
point3d = polygon.getPoint(0);
- assertTrue(point3d.getX() == env.getXMin()
- && point3d.getY() == env.getYMin());// && point3d.z ==
- // interval.vmin);
+ assertTrue(point3d.getX() == env.getXMin() && point3d.getY() == env.getYMin());// && point3d.z ==
+ // interval.vmin);
point3d = polygon.getPoint(1);
- assertTrue(point3d.getX() == env.getXMin()
- && point3d.getY() == env.getYMax());// && point3d.z ==
- // interval.vmax);
+ assertTrue(point3d.getX() == env.getXMin() && point3d.getY() == env.getYMax());// && point3d.z ==
+ // interval.vmax);
point3d = polygon.getPoint(2);
- assertTrue(point3d.getX() == env.getXMax()
- && point3d.getY() == env.getYMax());// && point3d.z ==
- // interval.vmin);
+ assertTrue(point3d.getX() == env.getXMax() && point3d.getY() == env.getYMax());// && point3d.z ==
+ // interval.vmin);
point3d = polygon.getPoint(3);
- assertTrue(point3d.getX() == env.getXMax()
- && point3d.getY() == env.getYMin());// && point3d.z ==
- // interval.vmax);
+ assertTrue(point3d.getX() == env.getXMax() && point3d.getY() == env.getYMin());// && point3d.z ==
+ // interval.vmax);
Envelope1D interval;
interval = envelope.queryInterval(VertexDescription.Semantics.M, 0);
- double m = polygon.getAttributeAsDbl(VertexDescription.Semantics.M, 0,
- 0);
+ double m = polygon.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0);
assertTrue(m == interval.vmin);
m = polygon.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0);
assertTrue(m == interval.vmax);
@@ -274,8 +263,7 @@ public static void testImportExportShapeEnvelope() {
assertTrue(m == interval.vmax);
interval = envelope.queryInterval(VertexDescription.Semantics.ID, 0);
- double id = polygon.getAttributeAsDbl(VertexDescription.Semantics.ID,
- 0, 0);
+ double id = polygon.getAttributeAsDbl(VertexDescription.Semantics.ID, 0, 0);
assertTrue(id == interval.vmin);
id = polygon.getAttributeAsDbl(VertexDescription.Semantics.ID, 1, 0);
assertTrue(id == interval.vmax);
@@ -287,12 +275,10 @@ public static void testImportExportShapeEnvelope() {
@Test
public static void testImportExportWkbGeometryCollection() {
- OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkb);
int offset = 0;
- ByteBuffer wkbBuffer = ByteBuffer.allocate(600).order(
- ByteOrder.nativeOrder());
+ ByteBuffer wkbBuffer = ByteBuffer.allocate(600).order(ByteOrder.nativeOrder());
wkbBuffer.put(offset, (byte) WkbByteOrder.wkbNDR);
offset += 1; // byte order
wkbBuffer.putInt(offset, WkbGeometryType.wkbGeometryCollection);
@@ -342,7 +328,7 @@ public static void testImportExportWkbGeometryCollection() {
wkbBuffer.putInt(offset, WkbGeometryType.wkbGeometryCollection);
offset += 4;
wkbBuffer.putInt(offset, 0); // 0 geometries, for empty
- // geometrycollection
+ // geometrycollection
offset += 4;
wkbBuffer.put(offset, (byte) WkbByteOrder.wkbNDR);
offset += 1;
@@ -368,8 +354,7 @@ public static void testImportExportWkbGeometryCollection() {
offset += 8;
// "GeometryCollection( Point (0 0), GeometryCollection( LineString empty, Polygon empty, MultiPolygon empty, MultiLineString empty, MultiPoint empty ), Point (13 17) )";
- OGCStructure structure = importerWKB.executeOGC(0, wkbBuffer, null).m_structures
- .get(0);
+ OGCStructure structure = importerWKB.executeOGC(0, wkbBuffer, null).m_structures.get(0);
assertTrue(structure.m_type == 7);
assertTrue(structure.m_structures.get(0).m_type == 1);
@@ -395,17 +380,13 @@ public static void testImportExportWkbGeometryCollection() {
@Test
public static void testImportExportWKBPolygon() {
- OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkb);
- OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkt);
- OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkb);
+ OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
+ OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkb);
// Test Import Polygon with bad rings
int offset = 0;
- ByteBuffer wkbBuffer = ByteBuffer.allocate(500).order(
- ByteOrder.nativeOrder());
+ ByteBuffer wkbBuffer = ByteBuffer.allocate(500).order(ByteOrder.nativeOrder());
wkbBuffer.put(offset, (byte) WkbByteOrder.wkbNDR);
offset += 1; // byte order
wkbBuffer.putInt(offset, WkbGeometryType.wkbPolygon);
@@ -505,17 +486,13 @@ public static void testImportExportWKBPolygon() {
wkbBuffer.putDouble(offset, 67.0);
offset += 8; // y
- Geometry p = importerWKB.execute(0, Geometry.Type.Polygon, wkbBuffer,
- null);
+ Geometry p = importerWKB.execute(0, Geometry.Type.Polygon, wkbBuffer, null);
int pc = ((Polygon) p).getPathCount();
String wktString = exporterWKT.execute(0, p, null);
- assertTrue(wktString
- .equals("MULTIPOLYGON (((0 0, 10 10, 0 10, 0 0), (36 17, 36 17, 36 17), (19 19, -19 -19, 19 19), (23 88, 83 87, 59 79, 13 43, 23 88), (23 88, 67 79, 88 43, 23 88), (23 88, 67 88, 88 43, 23 88), (23 67, 43 67, 23 67)))"));
+ assertTrue(wktString.equals("MULTIPOLYGON (((0 0, 10 10, 0 10, 0 0), (36 17, 36 17, 36 17), (19 19, -19 -19, 19 19), (23 88, 83 87, 59 79, 13 43, 23 88), (23 88, 67 79, 88 43, 23 88), (23 88, 67 88, 88 43, 23 88), (23 67, 43 67, 23 67)))"));
- wktString = exporterWKT.execute(WktExportFlags.wktExportPolygon, p,
- null);
- assertTrue(wktString
- .equals("POLYGON ((0 0, 10 10, 0 10, 0 0), (36 17, 36 17, 36 17), (19 19, -19 -19, 19 19), (23 88, 83 87, 59 79, 13 43, 23 88), (23 88, 67 79, 88 43, 23 88), (23 88, 67 88, 88 43, 23 88), (23 67, 43 67, 23 67))"));
+ wktString = exporterWKT.execute(WktExportFlags.wktExportPolygon, p, null);
+ assertTrue(wktString.equals("POLYGON ((0 0, 10 10, 0 10, 0 0), (36 17, 36 17, 36 17), (19 19, -19 -19, 19 19), (23 88, 83 87, 59 79, 13 43, 23 88), (23 88, 67 79, 88 43, 23 88), (23 88, 67 88, 88 43, 23 88), (23 67, 43 67, 23 67))"));
Polygon polygon = makePolygon();
@@ -523,48 +500,37 @@ public static void testImportExportWKBPolygon() {
ByteBuffer polygonWKBBuffer = exporterWKB.execute(0, polygon, null);
int wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiPolygonZM);
- Geometry polygonWKBGeometry = importerWKB.execute(0,
- Geometry.Type.Polygon, polygonWKBBuffer, null);
- TestCommonMethods.compareGeometryContent(
- (MultiVertexGeometry) polygonWKBGeometry, polygon);
+ Geometry polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null);
+ TestCommonMethods.compareGeometryContent((MultiVertexGeometry) polygonWKBGeometry, polygon);
// Test WKB_export_multi_polygon on nonempty single part polygon
Polygon polygon2 = makePolygon2();
assertTrue(polygon2.getPathCount() == 1);
- polygonWKBBuffer = exporterWKB.execute(
- WkbExportFlags.wkbExportMultiPolygon, polygon2, null);
- polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon,
- polygonWKBBuffer, null);
- TestCommonMethods.compareGeometryContent(
- (MultiVertexGeometry) polygonWKBGeometry, polygon2);
+ polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportMultiPolygon, polygon2, null);
+ polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null);
+ TestCommonMethods.compareGeometryContent((MultiVertexGeometry) polygonWKBGeometry, polygon2);
wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiPolygonZM);
// Test WKB_export_polygon on nonempty single part polygon
assertTrue(polygon2.getPathCount() == 1);
- polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPolygon,
- polygon2, null);
- polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon,
- polygonWKBBuffer, null);
- TestCommonMethods.compareGeometryContent(
- (MultiVertexGeometry) polygonWKBGeometry, polygon2);
+ polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPolygon, polygon2, null);
+ polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null);
+ TestCommonMethods.compareGeometryContent((MultiVertexGeometry) polygonWKBGeometry, polygon2);
wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPolygonZM);
// Test WKB_export_polygon on empty polygon
Polygon polygon3 = new Polygon();
- polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPolygon,
- polygon3, null);
- polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon,
- polygonWKBBuffer, null);
+ polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPolygon, polygon3, null);
+ polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null);
assertTrue(polygonWKBGeometry.isEmpty() == true);
wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPolygon);
// Test WKB_export_defaults on empty polygon
polygonWKBBuffer = exporterWKB.execute(0, polygon3, null);
- polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon,
- polygonWKBBuffer, null);
+ polygonWKBGeometry = importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null);
assertTrue(polygonWKBGeometry.isEmpty() == true);
wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiPolygon);
@@ -572,18 +538,14 @@ public static void testImportExportWKBPolygon() {
@Test
public static void testImportExportWKBPolyline() {
- OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkb);
- OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkt);
- OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkb);
+ OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
+ OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkb);
// Test Import Polyline with bad paths (i.e. paths with one point or
// zero points)
int offset = 0;
- ByteBuffer wkbBuffer = ByteBuffer.allocate(500).order(
- ByteOrder.nativeOrder());
+ ByteBuffer wkbBuffer = ByteBuffer.allocate(500).order(ByteOrder.nativeOrder());
wkbBuffer.put(offset, (byte) WkbByteOrder.wkbNDR);
offset += 1; // byte order
wkbBuffer.putInt(offset, WkbGeometryType.wkbMultiLineString);
@@ -635,16 +597,14 @@ public static void testImportExportWKBPolyline() {
wkbBuffer.putDouble(offset, 88);
offset += 8; // y
- Polyline p = (Polyline) (importerWKB.execute(0, Geometry.Type.Polyline,
- wkbBuffer, null));
+ Polyline p = (Polyline) (importerWKB.execute(0, Geometry.Type.Polyline, wkbBuffer, null));
int pc = p.getPointCount();
int pac = p.getPathCount();
assertTrue(p.getPointCount() == 7);
assertTrue(p.getPathCount() == 3);
String wktString = exporterWKT.execute(0, p, null);
- assertTrue(wktString
- .equals("MULTILINESTRING ((36 17, 36 17), (19 19, 19 19), (88 29, 13 43, 59 88))"));
+ assertTrue(wktString.equals("MULTILINESTRING ((36 17, 36 17), (19 19, 19 19), (88 29, 13 43, 59 88))"));
Polyline polyline = makePolyline();
polyline.dropAttribute(VertexDescription.Semantics.ID);
@@ -653,48 +613,37 @@ public static void testImportExportWKBPolyline() {
ByteBuffer polylineWKBBuffer = exporterWKB.execute(0, polyline, null);
int wkbType = polylineWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiLineStringZM);
- Geometry polylineWKBGeometry = importerWKB.execute(0,
- Geometry.Type.Polyline, polylineWKBBuffer, null);
- TestCommonMethods.compareGeometryContent(
- (MultiVertexGeometry) polylineWKBGeometry, polyline);
+ Geometry polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline, polylineWKBBuffer, null);
+ TestCommonMethods.compareGeometryContent((MultiVertexGeometry) polylineWKBGeometry, polyline);
// Test wkbExportMultiPolyline on nonempty single part polyline
Polyline polyline2 = makePolyline2();
assertTrue(polyline2.getPathCount() == 1);
- polylineWKBBuffer = exporterWKB.execute(
- WkbExportFlags.wkbExportMultiLineString, polyline2, null);
- polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline,
- polylineWKBBuffer, null);
- TestCommonMethods.compareGeometryContent(
- (MultiVertexGeometry) polylineWKBGeometry, polyline2);
+ polylineWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportMultiLineString, polyline2, null);
+ polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline, polylineWKBBuffer, null);
+ TestCommonMethods.compareGeometryContent((MultiVertexGeometry) polylineWKBGeometry, polyline2);
wkbType = polylineWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiLineStringZM);
// Test wkbExportPolyline on nonempty single part polyline
assertTrue(polyline2.getPathCount() == 1);
- polylineWKBBuffer = exporterWKB.execute(
- WkbExportFlags.wkbExportLineString, polyline2, null);
- polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline,
- polylineWKBBuffer, null);
- TestCommonMethods.compareGeometryContent(
- (MultiVertexGeometry) polylineWKBGeometry, polyline2);
+ polylineWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportLineString, polyline2, null);
+ polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline, polylineWKBBuffer, null);
+ TestCommonMethods.compareGeometryContent((MultiVertexGeometry) polylineWKBGeometry, polyline2);
wkbType = polylineWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbLineStringZM);
// Test wkbExportPolyline on empty polyline
Polyline polyline3 = new Polyline();
- polylineWKBBuffer = exporterWKB.execute(
- WkbExportFlags.wkbExportLineString, polyline3, null);
- polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline,
- polylineWKBBuffer, null);
+ polylineWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportLineString, polyline3, null);
+ polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline, polylineWKBBuffer, null);
assertTrue(polylineWKBGeometry.isEmpty() == true);
wkbType = polylineWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbLineString);
// Test WKB_export_defaults on empty polyline
polylineWKBBuffer = exporterWKB.execute(0, polyline3, null);
- polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline,
- polylineWKBBuffer, null);
+ polylineWKBGeometry = importerWKB.execute(0, Geometry.Type.Polyline, polylineWKBBuffer, null);
assertTrue(polylineWKBGeometry.isEmpty() == true);
wkbType = polylineWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiLineString);
@@ -702,53 +651,42 @@ public static void testImportExportWKBPolyline() {
@Test
public static void testImportExportWKBMultiPoint() {
- OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkb);
- OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkb);
+ OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkb);
MultiPoint multipoint = makeMultiPoint();
multipoint.dropAttribute(VertexDescription.Semantics.ID);
// Test Import Multi_point from Multi_point
- ByteBuffer multipointWKBBuffer = exporterWKB.execute(0, multipoint,
- null);
+ ByteBuffer multipointWKBBuffer = exporterWKB.execute(0, multipoint, null);
int wkbType = multipointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiPointZ);
- MultiPoint multipointWKBGeometry = (MultiPoint) (importerWKB.execute(0,
- Geometry.Type.MultiPoint, multipointWKBBuffer, null));
- TestCommonMethods.compareGeometryContent(
- (MultiVertexGeometry) multipointWKBGeometry, multipoint);
+ MultiPoint multipointWKBGeometry = (MultiPoint) (importerWKB.execute(0, Geometry.Type.MultiPoint, multipointWKBBuffer, null));
+ TestCommonMethods.compareGeometryContent((MultiVertexGeometry) multipointWKBGeometry, multipoint);
// Test WKB_export_point on nonempty single point Multi_point
MultiPoint multipoint2 = makeMultiPoint2();
assertTrue(multipoint2.getPointCount() == 1);
- ByteBuffer pointWKBBuffer = exporterWKB.execute(
- WkbExportFlags.wkbExportPoint, multipoint2, null);
- Point pointWKBGeometry = (Point) (importerWKB.execute(0,
- Geometry.Type.Point, pointWKBBuffer, null));
+ ByteBuffer pointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPoint, multipoint2, null);
+ Point pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point, pointWKBBuffer, null));
Point3D point3d, mpoint3d;
point3d = pointWKBGeometry.getXYZ();
mpoint3d = multipoint2.getXYZ(0);
- assertTrue(point3d.x == mpoint3d.x && point3d.y == mpoint3d.y
- && point3d.z == mpoint3d.z);
+ assertTrue(point3d.x == mpoint3d.x && point3d.y == mpoint3d.y && point3d.z == mpoint3d.z);
wkbType = pointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPointZ);
// Test WKB_export_point on empty Multi_point
MultiPoint multipoint3 = new MultiPoint();
- pointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPoint,
- multipoint3, null);
- pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point,
- pointWKBBuffer, null));
+ pointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPoint, multipoint3, null);
+ pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point, pointWKBBuffer, null));
assertTrue(pointWKBGeometry.isEmpty() == true);
wkbType = pointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPoint);
// Test WKB_export_defaults on empty Multi_point
multipointWKBBuffer = exporterWKB.execute(0, multipoint3, null);
- multipointWKBGeometry = (MultiPoint) (importerWKB.execute(0,
- Geometry.Type.MultiPoint, multipointWKBBuffer, null));
+ multipointWKBGeometry = (MultiPoint) (importerWKB.execute(0, Geometry.Type.MultiPoint, multipointWKBBuffer, null));
assertTrue(multipointWKBGeometry.isEmpty() == true);
wkbType = multipointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiPoint);
@@ -756,10 +694,8 @@ public static void testImportExportWKBMultiPoint() {
@Test
public static void testImportExportWKBPoint() {
- OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkb);
- OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkb);
+ OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkb);
// Point
Point point = makePoint();
@@ -768,8 +704,7 @@ public static void testImportExportWKBPoint() {
ByteBuffer pointWKBBuffer = exporterWKB.execute(0, point, null);
int wkbType = pointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPointZM);
- Point pointWKBGeometry = (Point) (importerWKB.execute(0,
- Geometry.Type.Point, pointWKBBuffer, null));
+ Point pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point, pointWKBBuffer, null));
double x_1 = point.getX();
double x2 = pointWKBGeometry.getX();
@@ -790,27 +725,22 @@ public static void testImportExportWKBPoint() {
// Test WKB_export_defaults on empty point
Point point2 = new Point();
pointWKBBuffer = exporterWKB.execute(0, point2, null);
- pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point,
- pointWKBBuffer, null));
+ pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point, pointWKBBuffer, null));
assertTrue(pointWKBGeometry.isEmpty() == true);
wkbType = pointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPoint);
// Test WKB_export_point on empty point
- pointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPoint,
- point2, null);
- pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point,
- pointWKBBuffer, null));
+ pointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPoint, point2, null);
+ pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point, pointWKBBuffer, null));
assertTrue(pointWKBGeometry.isEmpty() == true);
wkbType = pointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPoint);
// Test WKB_export_multi_point on empty point
MultiPoint multipoint = new MultiPoint();
- ByteBuffer multipointWKBBuffer = exporterWKB.execute(
- WkbExportFlags.wkbExportMultiPoint, multipoint, null);
- MultiPoint multipointWKBGeometry = (MultiPoint) (importerWKB.execute(0,
- Geometry.Type.MultiPoint, multipointWKBBuffer, null));
+ ByteBuffer multipointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportMultiPoint, multipoint, null);
+ MultiPoint multipointWKBGeometry = (MultiPoint) (importerWKB.execute(0, Geometry.Type.MultiPoint, multipointWKBBuffer, null));
assertTrue(multipointWKBGeometry.isEmpty() == true);
wkbType = multipointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiPoint);
@@ -818,25 +748,20 @@ public static void testImportExportWKBPoint() {
// Test WKB_export_point on nonempty single point Multi_point
MultiPoint multipoint2 = makeMultiPoint2();
assertTrue(multipoint2.getPointCount() == 1);
- pointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPoint,
- multipoint2, null);
- pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point,
- pointWKBBuffer, null));
+ pointWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPoint, multipoint2, null);
+ pointWKBGeometry = (Point) (importerWKB.execute(0, Geometry.Type.Point, pointWKBBuffer, null));
Point3D point3d, mpoint3d;
point3d = pointWKBGeometry.getXYZ();
mpoint3d = multipoint2.getXYZ(0);
- assertTrue(point3d.x == mpoint3d.x && point3d.y == mpoint3d.y
- && point3d.z == mpoint3d.z);
+ assertTrue(point3d.x == mpoint3d.x && point3d.y == mpoint3d.y && point3d.z == mpoint3d.z);
wkbType = pointWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPointZ);
}
@Test
public static void testImportExportWKBEnvelope() {
- OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkb);
- OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ OperatorExportToWkb exporterWKB = (OperatorExportToWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkb);
+ OperatorImportFromWkb importerWKB = (OperatorImportFromWkb) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkb);
// Test Export Envelope to Polygon (WKB_export_defaults)
Envelope envelope = makeEnvelope();
@@ -845,8 +770,7 @@ public static void testImportExportWKBEnvelope() {
ByteBuffer polygonWKBBuffer = exporterWKB.execute(0, envelope, null);
int wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPolygonZM);
- Polygon polygon = (Polygon) (importerWKB.execute(0,
- Geometry.Type.Polygon, polygonWKBBuffer, null));
+ Polygon polygon = (Polygon) (importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null));
int point_count = polygon.getPointCount();
assertTrue(point_count == 4);
@@ -857,21 +781,16 @@ public static void testImportExportWKBEnvelope() {
interval = envelope.queryInterval(VertexDescription.Semantics.Z, 0);
Point3D point3d;
point3d = polygon.getXYZ(0);
- assertTrue(point3d.x == env.xmin && point3d.y == env.ymin
- && point3d.z == interval.vmin);
+ assertTrue(point3d.x == env.xmin && point3d.y == env.ymin && point3d.z == interval.vmin);
point3d = polygon.getXYZ(1);
- assertTrue(point3d.x == env.xmin && point3d.y == env.ymax
- && point3d.z == interval.vmax);
+ assertTrue(point3d.x == env.xmin && point3d.y == env.ymax && point3d.z == interval.vmax);
point3d = polygon.getXYZ(2);
- assertTrue(point3d.x == env.xmax && point3d.y == env.ymax
- && point3d.z == interval.vmin);
+ assertTrue(point3d.x == env.xmax && point3d.y == env.ymax && point3d.z == interval.vmin);
point3d = polygon.getXYZ(3);
- assertTrue(point3d.x == env.xmax && point3d.y == env.ymin
- && point3d.z == interval.vmax);
+ assertTrue(point3d.x == env.xmax && point3d.y == env.ymin && point3d.z == interval.vmax);
interval = envelope.queryInterval(VertexDescription.Semantics.M, 0);
- double m = polygon.getAttributeAsDbl(VertexDescription.Semantics.M, 0,
- 0);
+ double m = polygon.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0);
assertTrue(m == interval.vmin);
m = polygon.getAttributeAsDbl(VertexDescription.Semantics.M, 1, 0);
assertTrue(m == interval.vmax);
@@ -881,29 +800,23 @@ public static void testImportExportWKBEnvelope() {
assertTrue(m == interval.vmax);
// Test WKB_export_multi_polygon on nonempty Envelope
- polygonWKBBuffer = exporterWKB.execute(
- WkbExportFlags.wkbExportMultiPolygon, envelope, null);
+ polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportMultiPolygon, envelope, null);
wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbMultiPolygonZM);
- polygon = (Polygon) (importerWKB.execute(0, Geometry.Type.Polygon,
- polygonWKBBuffer, null));
+ polygon = (Polygon) (importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null));
point_count = polygon.getPointCount();
assertTrue(point_count == 4);
envelope.queryEnvelope2D(env);
interval = envelope.queryInterval(VertexDescription.Semantics.Z, 0);
point3d = polygon.getXYZ(0);
- assertTrue(point3d.x == env.xmin && point3d.y == env.ymin
- && point3d.z == interval.vmin);
+ assertTrue(point3d.x == env.xmin && point3d.y == env.ymin && point3d.z == interval.vmin);
point3d = polygon.getXYZ(1);
- assertTrue(point3d.x == env.xmin && point3d.y == env.ymax
- && point3d.z == interval.vmax);
+ assertTrue(point3d.x == env.xmin && point3d.y == env.ymax && point3d.z == interval.vmax);
point3d = polygon.getXYZ(2);
- assertTrue(point3d.x == env.xmax && point3d.y == env.ymax
- && point3d.z == interval.vmin);
+ assertTrue(point3d.x == env.xmax && point3d.y == env.ymax && point3d.z == interval.vmin);
point3d = polygon.getXYZ(3);
- assertTrue(point3d.x == env.xmax && point3d.y == env.ymin
- && point3d.z == interval.vmax);
+ assertTrue(point3d.x == env.xmax && point3d.y == env.ymin && point3d.z == interval.vmax);
interval = envelope.queryInterval(VertexDescription.Semantics.M, 0);
m = polygon.getAttributeAsDbl(VertexDescription.Semantics.M, 0, 0);
@@ -920,34 +833,28 @@ public static void testImportExportWKBEnvelope() {
polygonWKBBuffer = exporterWKB.execute(0, envelope2, null);
wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPolygon);
- polygon = (Polygon) (importerWKB.execute(0, Geometry.Type.Polygon,
- polygonWKBBuffer, null));
+ polygon = (Polygon) (importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null));
assertTrue(polygon.isEmpty());
// Test WKB_export_polygon on empty Envelope
- polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPolygon,
- envelope2, null);
+ polygonWKBBuffer = exporterWKB.execute(WkbExportFlags.wkbExportPolygon, envelope2, null);
wkbType = polygonWKBBuffer.getInt(1);
assertTrue(wkbType == WkbGeometryType.wkbPolygon);
- polygon = (Polygon) (importerWKB.execute(0, Geometry.Type.Polygon,
- polygonWKBBuffer, null));
+ polygon = (Polygon) (importerWKB.execute(0, Geometry.Type.Polygon, polygonWKBBuffer, null));
assertTrue(polygon.isEmpty());
}
@Test
public static void testImportExportWktGeometryCollection() {
- OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkt);
- OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkt);
+ OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkt);
+ OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
String wktString;
Envelope2D envelope = new Envelope2D();
WktParser wktParser = new WktParser();
wktString = "GeometryCollection( Point (0 0), GeometryCollection( Point (0 0) , Point (1 1) , Point (2 2), LineString empty ), Point (1 1), Point (2 2) )";
- OGCStructure structure = importerWKT.executeOGC(0, wktString, null).m_structures
- .get(0);
+ OGCStructure structure = importerWKT.executeOGC(0, wktString, null).m_structures.get(0);
assertTrue(structure.m_type == 7);
assertTrue(structure.m_structures.get(0).m_type == 1);
@@ -964,10 +871,8 @@ public static void testImportExportWktGeometryCollection() {
@Test
public static void testImportExportWktMultiPolygon() {
- OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkt);
- OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkt);
+ OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkt);
+ OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
Polygon polygon;
String wktString;
@@ -975,16 +880,13 @@ public static void testImportExportWktMultiPolygon() {
WktParser wktParser = new WktParser();
// Test Import from MultiPolygon
-
wktString = "Multipolygon M empty";
- polygon = (Polygon) importerWKT.execute(0, Geometry.Type.Polygon,
- wktString, null);
+ polygon = (Polygon) importerWKT.execute(0, Geometry.Type.Polygon, wktString, null);
assertTrue(polygon != null);
assertTrue(polygon.isEmpty());
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.M));
- polygon = (Polygon) GeometryEngine.geometryFromWkt(wktString, 0,
- Geometry.Type.Unknown);
+ polygon = (Polygon) GeometryEngine.geometryFromWkt(wktString, 0, Geometry.Type.Unknown);
assertTrue(polygon != null);
assertTrue(polygon.isEmpty());
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.M));
@@ -996,43 +898,36 @@ public static void testImportExportWktMultiPolygon() {
assertTrue(wktString.equals("MULTIPOLYGON M EMPTY"));
wktString = "Multipolygon Z (empty, (empty, (10 10 5, 20 10 5, 20 20 5, 10 20 5, 10 10 5), (12 12 3), empty, (10 10 1, 12 12 1)), empty, ((90 90 88, 60 90 7, 60 60 7), empty, (70 70 7, 80 80 7, 70 80 7, 70 70 7)), empty)";
- polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon,
- wktString, null));
+ polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon, wktString, null));
assertTrue(polygon != null);
polygon.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 90
- && envelope.ymin == 10 && envelope.ymax == 90);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 90 && envelope.ymin == 10 && envelope.ymax == 90);
assertTrue(polygon.getPointCount() == 14);
assertTrue(polygon.getPathCount() == 5);
// assertTrue(polygon.calculate_area_2D() > 0.0);
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
- double z = polygon.getAttributeAsDbl(VertexDescription.Semantics.Z, 0,
- 0);
+ double z = polygon.getAttributeAsDbl(VertexDescription.Semantics.Z, 0, 0);
assertTrue(z == 5);
// Test Export to WKT MultiPolygon
wktString = exporterWKT.execute(0, polygon, null);
- assertTrue(wktString
- .equals("MULTIPOLYGON Z (((10 10 5, 20 10 5, 20 20 5, 10 20 5, 10 10 5), (12 12 3, 12 12 3, 12 12 3), (10 10 1, 12 12 1, 10 10 1)), ((90 90 88, 60 90 7, 60 60 7, 90 90 88), (70 70 7, 80 80 7, 70 80 7, 70 70 7)))"));
+ assertTrue(wktString.equals("MULTIPOLYGON Z (((10 10 5, 20 10 5, 20 20 5, 10 20 5, 10 10 5), (12 12 3, 12 12 3, 12 12 3), (10 10 1, 12 12 1, 10 10 1)), ((90 90 88, 60 90 7, 60 60 7, 90 90 88), (70 70 7, 70 80 7, 80 80 7, 70 70 7)))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
// Test import Polygon
wktString = "POLYGON z (EMPTY, EMPTY, (10 10 5, 10 20 5, 20 20 5, 20 10 5), (12 12 3), EMPTY, (10 10 1, 12 12 1), EMPTY, (60 60 7, 60 90 7, 90 90 7, 60 60 7), EMPTY, (70 70 7, 70 80 7, 80 80 7), EMPTY)";
- polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon,
- wktString, null));
+ polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon, wktString, null));
assertTrue(polygon != null);
assertTrue(polygon.getPointCount() == 14);
assertTrue(polygon.getPathCount() == 5);
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
// Test Export to WKT Polygon
- wktString = exporterWKT.execute(WktExportFlags.wktExportPolygon,
- polygon, null);
- assertTrue(wktString
- .equals("POLYGON Z ((10 10 5, 20 10 5, 20 20 5, 10 20 5, 10 10 5), (12 12 3, 12 12 3, 12 12 3), (10 10 1, 12 12 1, 10 10 1), (60 60 7, 90 90 7, 60 90 7, 60 60 7), (70 70 7, 80 80 7, 70 80 7, 70 70 7))"));
+ wktString = exporterWKT.execute(WktExportFlags.wktExportPolygon, polygon, null);
+ assertTrue(wktString.equals("POLYGON Z ((10 10 5, 20 10 5, 20 20 5, 10 20 5, 10 10 5), (12 12 3, 12 12 3, 12 12 3), (10 10 1, 12 12 1, 10 10 1), (60 60 7, 60 90 7, 90 90 7, 60 60 7), (70 70 7, 70 80 7, 80 80 7, 70 70 7))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
@@ -1042,16 +937,13 @@ public static void testImportExportWktMultiPolygon() {
polygon.queryEnvelope(env);
wktString = exporterWKT.execute(0, env, null);
- assertTrue(wktString
- .equals("POLYGON Z ((10 10 1, 90 10 7, 90 90 1, 10 90 7, 10 10 1))"));
+ assertTrue(wktString.equals("POLYGON Z ((10 10 1, 90 10 7, 90 90 1, 10 90 7, 10 10 1))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
- wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPolygon,
- env, null);
- assertTrue(wktString
- .equals("MULTIPOLYGON Z (((10 10 1, 90 10 7, 90 90 1, 10 90 7, 10 10 1)))"));
+ wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPolygon, env, null);
+ assertTrue(wktString.equals("MULTIPOLYGON Z (((10 10 1, 90 10 7, 90 90 1, 10 90 7, 10 10 1)))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
@@ -1064,44 +956,38 @@ public static void testImportExportWktMultiPolygon() {
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
- wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPolygon,
- env, null);
+ wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPolygon, env, null);
assertTrue(wktString.equals("MULTIPOLYGON Z EMPTY"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
wktString = "MULTIPOLYGON (((5 10, 8 10, 10 10, 10 0, 0 0, 0 10, 2 10, 5 10)))"; // ring
- // is
- // oriented
- // clockwise
- polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon,
- wktString, null));
+ // is
+ // oriented
+ // clockwise
+ polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon, wktString, null));
assertTrue(polygon != null);
assertTrue(polygon.calculateArea2D() > 0);
wktString = "MULTIPOLYGON Z (((90 10 7, 10 10 1, 10 90 7, 90 90 1, 90 10 7)))"; // ring
- // is
- // oriented
- // clockwise
- polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon,
- wktString, null));
+ // is
+ // oriented
+ // clockwise
+ polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Polygon, wktString, null));
assertTrue(polygon != null);
assertTrue(polygon.getPointCount() == 4);
assertTrue(polygon.getPathCount() == 1);
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(polygon.calculateArea2D() > 0);
- wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPolygon,
- polygon, null);
- assertTrue(wktString
- .equals("MULTIPOLYGON Z (((90 10 7, 90 90 1, 10 90 7, 10 10 1, 90 10 7)))"));
+ wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPolygon, polygon, null);
+ assertTrue(wktString.equals("MULTIPOLYGON Z (((90 10 7, 90 90 1, 10 90 7, 10 10 1, 90 10 7)))"));
}
@Test
public static void testImportExportWktPolygon() {
- OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkt);
+ OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkt);
// OperatorExportToWkt exporterWKT =
// (OperatorExportToWkt)OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
@@ -1110,29 +996,24 @@ public static void testImportExportWktPolygon() {
Envelope2D envelope = new Envelope2D();
// Test Import from Polygon
-
wktString = "Polygon ZM empty";
- polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polygon != null);
assertTrue(polygon.isEmpty());
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.M));
wktString = "Polygon z (empty, (10 10 5, 20 10 5, 20 20 5, 10 20 5, 10 10 5), (12 12 3), empty, (10 10 1, 12 12 1))";
- polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ polygon = (Polygon) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polygon != null);
polygon.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 20
- && envelope.ymin == 10 && envelope.ymax == 20);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 20 && envelope.ymin == 10 && envelope.ymax == 20);
assertTrue(polygon.getPointCount() == 8);
assertTrue(polygon.getPathCount() == 3);
assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
wktString = "polygon ((35 10, 10 20, 15 40, 45 45, 35 10), (20 30, 35 35, 30 20, 20 30))";
- Polygon polygon2 = (Polygon) (importerWKT.execute(0,
- Geometry.Type.Unknown, wktString, null));
+ Polygon polygon2 = (Polygon) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polygon2 != null);
// wktString = exporterWKT.execute(0, *polygon2, null);
@@ -1140,8 +1021,7 @@ public static void testImportExportWktPolygon() {
@Test
public static void testImportExportWktLineString() {
- OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkt);
+ OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkt);
// OperatorExportToWkt exporterWKT =
// (OperatorExportToWkt)OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
@@ -1150,22 +1030,18 @@ public static void testImportExportWktLineString() {
Envelope2D envelope = new Envelope2D();
// Test Import from LineString
-
wktString = "LineString ZM empty";
- polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polyline != null);
assertTrue(polyline.isEmpty());
assertTrue(polyline.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(polyline.hasAttribute(VertexDescription.Semantics.M));
wktString = "LineString m (10 10 5, 10 20 5, 20 20 5, 20 10 5)";
- polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polyline != null);
polyline.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 20
- && envelope.ymin == 10 && envelope.ymax == 20);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 20 && envelope.ymin == 10 && envelope.ymax == 20);
assertTrue(polyline.getPointCount() == 4);
assertTrue(polyline.getPathCount() == 1);
assertTrue(polyline.hasAttribute(VertexDescription.Semantics.M));
@@ -1173,10 +1049,8 @@ public static void testImportExportWktLineString() {
@Test
public static void testImportExportWktMultiLineString() {
- OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkt);
- OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkt);
+ OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkt);
+ OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
Polyline polyline;
String wktString;
@@ -1184,49 +1058,40 @@ public static void testImportExportWktMultiLineString() {
WktParser wktParser = new WktParser();
// Test Import from MultiLineString
-
wktString = "MultiLineStringZMempty";
- polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polyline != null);
assertTrue(polyline.isEmpty());
assertTrue(polyline.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(polyline.hasAttribute(VertexDescription.Semantics.M));
wktString = "MultiLineStringm(empty, empty, (10 10 5, 10 20 5, 20 88 5, 20 10 5), (12 88 3), empty, (10 10 1, 12 12 1), empty, (88 60 7, 60 90 7, 90 90 7), empty, (70 70 7, 70 80 7, 80 80 7), empty)";
- polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polyline != null);
polyline.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 90
- && envelope.ymin == 10 && envelope.ymax == 90);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 90 && envelope.ymin == 10 && envelope.ymax == 90);
assertTrue(polyline.getPointCount() == 14);
assertTrue(polyline.getPathCount() == 5);
assertTrue(polyline.hasAttribute(VertexDescription.Semantics.M));
wktString = exporterWKT.execute(0, polyline, null);
- assertTrue(wktString
- .equals("MULTILINESTRING M ((10 10 5, 10 20 5, 20 88 5, 20 10 5), (12 88 3, 12 88 3), (10 10 1, 12 12 1), (88 60 7, 60 90 7, 90 90 7), (70 70 7, 70 80 7, 80 80 7))"));
+ assertTrue(wktString.equals("MULTILINESTRING M ((10 10 5, 10 20 5, 20 88 5, 20 10 5), (12 88 3, 12 88 3), (10 10 1, 12 12 1), (88 60 7, 60 90 7, 90 90 7), (70 70 7, 70 80 7, 80 80 7))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
// Test Import LineString
wktString = "Linestring Z(10 10 5, 10 20 5, 20 20 5, 20 10 5)";
- polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ polyline = (Polyline) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(polyline.getPointCount() == 4);
- wktString = exporterWKT.execute(WktExportFlags.wktExportLineString,
- polyline, null);
- assertTrue(wktString
- .equals("LINESTRING Z (10 10 5, 10 20 5, 20 20 5, 20 10 5)"));
+ wktString = exporterWKT.execute(WktExportFlags.wktExportLineString, polyline, null);
+ assertTrue(wktString.equals("LINESTRING Z (10 10 5, 10 20 5, 20 20 5, 20 10 5)"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
wktString = exporterWKT.execute(0, polyline, null);
- assertTrue(wktString
- .equals("MULTILINESTRING Z ((10 10 5, 10 20 5, 20 20 5, 20 10 5))"));
+ assertTrue(wktString.equals("MULTILINESTRING Z ((10 10 5, 10 20 5, 20 20 5, 20 10 5))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
@@ -1234,10 +1099,8 @@ public static void testImportExportWktMultiLineString() {
@Test
public static void testImportExportWktMultiPoint() {
- OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkt);
- OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkt);
+ OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkt);
+ OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
MultiPoint multipoint;
String wktString;
@@ -1245,10 +1108,8 @@ public static void testImportExportWktMultiPoint() {
WktParser wktParser = new WktParser();
// Test Import from Multi_point
-
wktString = " MultiPoint ZM empty";
- multipoint = (MultiPoint) (importerWKT.execute(0,
- Geometry.Type.Unknown, wktString, null));
+ multipoint = (MultiPoint) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(multipoint != null);
assertTrue(multipoint.isEmpty());
assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
@@ -1260,8 +1121,7 @@ public static void testImportExportWktMultiPoint() {
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
- wktString = exporterWKT.execute(WktExportFlags.wktExportPoint,
- multipoint, null);
+ wktString = exporterWKT.execute(WktExportFlags.wktExportPoint, multipoint, null);
assertTrue(wktString.equals("POINT ZM EMPTY"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
@@ -1271,10 +1131,8 @@ public static void testImportExportWktMultiPoint() {
multipoint.add(118.15114354234563, 33.82234433423462345);
multipoint.add(88, 88);
- wktString = exporterWKT.execute(WktExportFlags.wktExportPrecision10,
- multipoint, null);
- assertTrue(wktString
- .equals("MULTIPOINT ((118.1511435 33.82234433), (88 88))"));
+ wktString = exporterWKT.execute(WktExportFlags.wktExportPrecision10, multipoint, null);
+ assertTrue(wktString.equals("MULTIPOINT ((118.1511435 33.82234433), (88 88))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
@@ -1290,8 +1148,7 @@ public static void testImportExportWktMultiPoint() {
}
wktString = "Multipoint zm (empty, empty, (10 88 88 33), (10 20 5 33), (20 20 5 33), (20 10 5 33), (12 12 3 33), empty, (10 10 1 33), (12 12 1 33), empty, (60 60 7 33), (60 90.1 7 33), (90 90 7 33), empty, (70 70 7 33), (70 80 7 33), (80 80 7 33), empty)";
- multipoint = (MultiPoint) (importerWKT.execute(0,
- Geometry.Type.Unknown, wktString, null));
+ multipoint = (MultiPoint) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(multipoint != null);
multipoint.queryEnvelope2D(envelope);
// assertTrue(envelope.xmin == 10 && envelope.xmax == 90 &&
@@ -1301,8 +1158,7 @@ public static void testImportExportWktMultiPoint() {
assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.M));
wktString = "Multipoint zm (10 88 88 33, 10 20 5 33, 20 20 5 33, 20 10 5 33, 12 12 3 33, 10 10 1 33, 12 12 1 33, 60 60 7 33, 60 90.1 7 33, 90 90 7 33, 70 70 7 33, 70 80 7 33, 80 80 7 33)";
- multipoint = (MultiPoint) (importerWKT.execute(0,
- Geometry.Type.Unknown, wktString, null));
+ multipoint = (MultiPoint) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(multipoint != null);
// assertTrue(envelope.xmin == 10 && envelope.xmax == 90 &&
// envelope.ymin == 10 && ::fabs(envelope.ymax - 90.1) <= 0.001);
@@ -1310,20 +1166,16 @@ public static void testImportExportWktMultiPoint() {
assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.M));
- wktString = exporterWKT.execute(WktExportFlags.wktExportPrecision15,
- multipoint, null);
- assertTrue(wktString
- .equals("MULTIPOINT ZM ((10 88 88 33), (10 20 5 33), (20 20 5 33), (20 10 5 33), (12 12 3 33), (10 10 1 33), (12 12 1 33), (60 60 7 33), (60 90.1 7 33), (90 90 7 33), (70 70 7 33), (70 80 7 33), (80 80 7 33))"));
+ wktString = exporterWKT.execute(WktExportFlags.wktExportPrecision15, multipoint, null);
+ assertTrue(wktString.equals("MULTIPOINT ZM ((10 88 88 33), (10 20 5 33), (20 20 5 33), (20 10 5 33), (12 12 3 33), (10 10 1 33), (12 12 1 33), (60 60 7 33), (60 90.1 7 33), (90 90 7 33), (70 70 7 33), (70 80 7 33), (80 80 7 33))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
wktString = "Multipoint zm (empty, empty, (10 10 5 33))";
- multipoint = (MultiPoint) (importerWKT.execute(0,
- Geometry.Type.Unknown, wktString, null));
+ multipoint = (MultiPoint) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
- wktString = exporterWKT.execute(WktExportFlags.wktExportPoint,
- multipoint, null);
+ wktString = exporterWKT.execute(WktExportFlags.wktExportPoint, multipoint, null);
assertTrue(wktString.equals("POINT ZM (10 10 5 33)"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
@@ -1332,20 +1184,16 @@ public static void testImportExportWktMultiPoint() {
@Test
public static void testImportExportWktPoint() {
- OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkt);
- OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkt);
+ OperatorImportFromWkt importerWKT = (OperatorImportFromWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromWkt);
+ OperatorExportToWkt exporterWKT = (OperatorExportToWkt) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkt);
Point point;
String wktString;
WktParser wktParser = new WktParser();
// Test Import from Point
-
wktString = "Point ZM empty";
- point = (Point) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ point = (Point) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(point != null);
assertTrue(point.isEmpty());
assertTrue(point.hasAttribute(VertexDescription.Semantics.Z));
@@ -1357,16 +1205,14 @@ public static void testImportExportWktPoint() {
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
- wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPoint,
- point, null);
+ wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPoint, point, null);
assertTrue(wktString.equals("MULTIPOINT ZM EMPTY"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
wktString = "Point zm (30.1 10.6 5.1 33.1)";
- point = (Point) (importerWKT.execute(0, Geometry.Type.Unknown,
- wktString, null));
+ point = (Point) (importerWKT.execute(0, Geometry.Type.Unknown, wktString, null));
assertTrue(point != null);
assertTrue(point.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(point.hasAttribute(VertexDescription.Semantics.M));
@@ -1380,34 +1226,30 @@ public static void testImportExportWktPoint() {
assertTrue(z == 5.1);
assertTrue(m == 33.1);
- wktString = exporterWKT.execute(WktExportFlags.wktExportPrecision15,
- point, null);
+ wktString = exporterWKT.execute(WktExportFlags.wktExportPrecision15, point, null);
assertTrue(wktString.equals("POINT ZM (30.1 10.6 5.1 33.1)"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
- wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPoint
- | WktExportFlags.wktExportPrecision15, point, null);
+ wktString = exporterWKT.execute(WktExportFlags.wktExportMultiPoint | WktExportFlags.wktExportPrecision15, point, null);
assertTrue(wktString.equals("MULTIPOINT ZM ((30.1 10.6 5.1 33.1))"));
wktParser.resetParser(wktString);
while (wktParser.nextToken() != WktParser.WktToken.not_available) {
}
}
+ @Deprecated
@Test
- public static void testImportGeoJsonGeometryCollection()
- throws JSONException {
- OperatorImportFromGeoJson importer = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ public static void testImportGeoJsonGeometryCollection() {
+ OperatorImportFromGeoJson importer = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
String geoJsonString;
Envelope2D envelope = new Envelope2D();
WktParser wktParser = new WktParser();
geoJsonString = "{\"type\" : \"GeometryCollection\", \"geometries\" : [{\"type\" : \"Point\", \"coordinates\": [0,0]}, {\"type\" : \"GeometryCollection\" , \"geometries\" : [ {\"type\" : \"Point\", \"coordinates\" : [0, 0]} , {\"type\" : \"Point\", \"coordinates\" : [1, 1]} ,{ \"type\" : \"Point\", \"coordinates\" : [2, 2]}, {\"type\" : \"LineString\", \"coordinates\" : []}]} , {\"type\" : \"Point\", \"coordinates\" : [1, 1]}, {\"type\" : \"Point\" , \"coordinates\" : [2, 2]} ] }";
- OGCStructure structure = importer.executeOGC(0, geoJsonString, null).m_ogcStructure.m_structures
- .get(0);
+ OGCStructure structure = importer.executeOGC(0, geoJsonString, null).m_ogcStructure.m_structures.get(0);
assertTrue(structure.m_type == 7);
assertTrue(structure.m_structures.get(0).m_type == 1);
@@ -1423,290 +1265,500 @@ public static void testImportGeoJsonGeometryCollection()
}
@Test
- public static void testImportGeoJsonMultiPolygon() throws JSONException {
- OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ public static void testImportGeoJsonMultiPolygon() throws Exception {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ OperatorExportToGeoJson exporterGeoJson = (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToGeoJson);
+ MapGeometry map_geometry;
Polygon polygon;
+ SpatialReference spatial_reference;
String geoJsonString;
Envelope2D envelope = new Envelope2D();
// Test Import from MultiPolygon
-
- geoJsonString = "{\"type\": \"Multipolygon\", \"coordinates\": []}";
- polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Polygon,
- geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\": \"MultiPolygon\", \"coordinates\": []}";
+ polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null).getGeometry());
assertTrue(polygon != null);
assertTrue(polygon.isEmpty());
assertTrue(!polygon.hasAttribute(VertexDescription.Semantics.M));
- polygon = (Polygon) (GeometryEngine.geometryFromGeoJson(geoJsonString,
- 0, Geometry.Type.Unknown).getGeometry());
+ geoJsonString = "{\"coordinates\" : [], \"type\": \"MultiPolygon\", \"crs\": {\"type\": \"name\", \"some\": \"stuff\", \"properties\": {\"some\" : \"stuff\", \"name\": \"urn:ogc:def:crs:OGC:1.3:CRS84\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(polygon != null);
assertTrue(polygon.isEmpty());
- assertTrue(!polygon.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(spatial_reference.getLatestID() == 4326);
- geoJsonString = "{\"type\": \"Multipolygon\", \"coordinates\": [[], [[], [[10, 10, 5], [20, 10, 5], [20, 20, 5], [10, 20, 5], [10, 10, 5]], [[12, 12, 3]], [], [[10, 10, 1], [12, 12, 1]]], [], [[[90, 90, 88], [60, 90, 7], [60, 60, 7]], [], [[70, 70, 7], [80, 80, 7], [70, 80, 7], [70, 70, 7]]], []]}";
- polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Polygon,
- geoJsonString, null).getGeometry());
+ geoJsonString = "{\"coordinates\" : null, \"crs\": null, \"type\": \"MultiPolygon\"}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
+ assertTrue(polygon != null);
+ assertTrue(polygon.isEmpty());
+ assertTrue(spatial_reference == null);
+
+ geoJsonString = "{\"type\": \"MultiPolygon\", \"coordinates\" : [[], [], [[[]]]], \"crsURN\": \"urn:ogc:def:crs:OGC:1.3:CRS27\"}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
+ assertTrue(polygon != null);
+ assertTrue(polygon.isEmpty());
+ assertTrue(spatial_reference != null);
+ assertTrue(spatial_reference.getLatestID() == 4267);
+
+ geoJsonString = "{\"coordinates\" : [[], [[], [[10, 10, 5], [20, 10, 5], [20, 20, 5], [10, 20, 5], [10, 10, 5]], [[12, 12, 3]], [], [[10, 10, 1], [12, 12, 1]]], [], [[[90, 90, 88], [60, 90, 7], [60, 60, 7]], [], [[70, 70, 7], [80, 80, 7], [70, 80, 7], [70, 70, 7]]], []], \"crs\": {\"type\": \"link\", \"properties\": {\"href\": \"http://spatialreference.org/ref/sr-org/6928/ogcwkt/\"}}, \"type\": \"MultiPolygon\"}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(polygon != null);
polygon.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 90
- && envelope.ymin == 10 && envelope.ymax == 90);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 90 && envelope.ymin == 10 && envelope.ymax == 90);
assertTrue(polygon.getPointCount() == 14);
assertTrue(polygon.getPathCount() == 5);
- // assertTrue(polygon.calculate_area_2D() > 0.0);
- // assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(spatial_reference.getLatestID() == 3857);
- // double z = polygon.getAttributeAsDbl(VertexDescription.Semantics.Z,
- // 0, 0);
- // assertTrue(z == 5);
-
- // Test import Polygon
- geoJsonString = "{\"type\": \"POLYGON\", \"coordinates\": [[], [], [[10, 10, 5], [10, 20, 5], [20, 20, 5], [20, 10, 5]], [[12, 12, 3]], [], [[10, 10, 1], [12, 12, 1]], [], [[60, 60, 7], [60, 90, 7], [90, 90, 7], [60, 60, 7]], [], [[70, 70, 7], [70, 80, 7], [80, 80, 7]], []] }";
- polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Polygon,
- geoJsonString, null).getGeometry());
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(polygon != null);
+ polygon.queryEnvelope2D(envelope);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 90 && envelope.ymin == 10 && envelope.ymax == 90);
assertTrue(polygon.getPointCount() == 14);
assertTrue(polygon.getPathCount() == 5);
- // assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
-
- geoJsonString = "{\"type\": \"MULTIPOLYGON\", \"coordinates\": [[[[90, 10, 7], [10, 10, 1], [10, 90, 7], [90, 90, 1], [90, 10, 7]]]] }"; // ring
- // is
- // oriented
- // clockwise
- polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Polygon,
- geoJsonString, null).getGeometry());
+ assertTrue(spatial_reference.getLatestID() == 3857);
+
+ // Test Export to GeoJSON MultiPolygon
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportSkipCRS, spatial_reference, polygon);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[10,10,5],[20,10,5],[20,20,5],[10,20,5],[10,10,5]],[[12,12,3],[12,12,3],[12,12,3]],[[10,10,1],[12,12,1],[10,10,1]]],[[[90,90,88],[60,90,7],[60,60,7],[90,90,88]],[[70,70,7],[70,80,7],[80,80,7],[70,70,7]]]]}"));
+
+ geoJsonString = exporterGeoJson.execute(0, spatial_reference, polygon);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[10,10,5],[20,10,5],[20,20,5],[10,20,5],[10,10,5]],[[12,12,3],[12,12,3],[12,12,3]],[[10,10,1],[12,12,1],[10,10,1]]],[[[90,90,88],[60,90,7],[60,60,7],[90,90,88]],[[70,70,7],[70,80,7],[80,80,7],[70,70,7]]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:3857\"}}}"));
+
+ geoJsonString = "{\"type\": \"MultiPolygon\", \"coordinates\": [[[[90, 10, 7], [10, 10, 1], [10, 90, 7], [90, 90, 1], [90, 10, 7]]]] }"; // ring
+ // i // clockwise
+ polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null).getGeometry());
assertTrue(polygon != null);
assertTrue(polygon.getPointCount() == 4);
assertTrue(polygon.getPathCount() == 1);
- // assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(polygon.calculateArea2D() > 0);
+
+ // Test import Polygon
+ geoJsonString = "{\"type\": \"Polygon\", \"coordinates\": [[], [], [[10, 10, 5], [10, 20, 5], [20, 20, 5], [20, 10, 5]], [[12, 12, 3]], [], [[10, 10, 1], [12, 12, 1]], [], [[60, 60, 7], [60, 90, 7], [90, 90, 7], [60, 60, 7]], [], [[70, 70, 7], [70, 80, 7], [80, 80, 7]], []] }";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
+ assertTrue(polygon != null);
+ assertTrue(polygon.getPointCount() == 14);
+ assertTrue(polygon.getPathCount() == 5);
+ assertTrue(spatial_reference.getLatestID() == 4326);
+
+ geoJsonString = exporterGeoJson.execute(0, spatial_reference, polygon);
+ assertTrue(geoJsonString.equals("{\"type\":\"Polygon\",\"coordinates\":[[[10,10,5],[20,10,5],[20,20,5],[10,20,5],[10,10,5]],[[12,12,3],[12,12,3],[12,12,3]],[[10,10,1],[12,12,1],[10,10,1]],[[60,60,7],[60,90,7],[90,90,7],[60,60,7]],[[70,70,7],[70,80,7],[80,80,7],[70,70,7]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}"));
+
+ Envelope env = new Envelope();
+ env.addAttribute(VertexDescription.Semantics.Z);
+ polygon.queryEnvelope(env);
+
+ geoJsonString = "{\"coordinates\" : [], \"type\": \"MultiPolygon\", \"crs\":{\"esriwkt\":\"PROJCS[\\\"Gnomonic\\\",GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137.0,298.257223563]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Gnomonic\\\"],PARAMETER[\\\"Longitude_Of_Center\\\",0.0],PARAMETER[\\\"Latitude_Of_Center\\\",-45.0],UNIT[\\\"Meter\\\",1.0]]\"}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
+ String wkt = spatial_reference.getText();
+ assertTrue(wkt.equals(
+ "PROJCS[\"Gnomonic\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gnomonic\"],PARAMETER[\"Longitude_Of_Center\",0.0],PARAMETER[\"Latitude_Of_Center\",-45.0],UNIT[\"Meter\",1.0]]"));
+
+ geoJsonString = "{\"coordinates\" : [], \"type\": \"MultiPolygon\", \"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"PROJCS[\\\"Gnomonic\\\",GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137.0,298.257223563]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Gnomonic\\\"],PARAMETER[\\\"Longitude_Of_Center\\\",0.0],PARAMETER[\\\"Latitude_Of_Center\\\",-45.0],UNIT[\\\"Meter\\\",1.0]]\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
+ wkt = spatial_reference.getText();
+ assertTrue(wkt.equals(
+ "PROJCS[\"Gnomonic\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gnomonic\"],PARAMETER[\"Longitude_Of_Center\",0.0],PARAMETER[\"Latitude_Of_Center\",-45.0],UNIT[\"Meter\",1.0]]"));
+ assertTrue(polygon != null);
+ assertTrue(polygon.isEmpty());
+
+ // AGOL exports wkt like this...
+ geoJsonString = "{\"coordinates\" : [], \"type\": \"MultiPolygon\", \"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"ESRI:PROJCS[\\\"Gnomonic\\\",GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137.0,298.257223563]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Gnomonic\\\"],PARAMETER[\\\"Longitude_Of_Center\\\",0.0],PARAMETER[\\\"Latitude_Of_Center\\\",-45.0],UNIT[\\\"Meter\\\",1.0]]\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Polygon, geoJsonString, null);
+ polygon = (Polygon) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
+ wkt = spatial_reference.getText();
+ assertTrue(wkt.equals(
+ "PROJCS[\"Gnomonic\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gnomonic\"],PARAMETER[\"Longitude_Of_Center\",0.0],PARAMETER[\"Latitude_Of_Center\",-45.0],UNIT[\"Meter\",1.0]]"));
+ assertTrue(polygon != null);
+ assertTrue(polygon.isEmpty());
+
+ boolean exceptionThrownNoWKT = false;
+
+ try {
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportPreferMultiGeometry,
+ spatial_reference, polygon);
+ } catch (Exception e) {
+ exceptionThrownNoWKT = true;
+ }
+
+ assertTrue(exceptionThrownNoWKT);
}
@Test
- public static void testImportGeoJsonMultiLineString() throws JSONException {
- OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
-
+ public static void testImportGeoJsonMultiLineString() throws Exception {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ OperatorExportToGeoJson exporterGeoJson = (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToGeoJson);
+ MapGeometry map_geometry;
Polyline polyline;
+ SpatialReference spatial_reference;
String geoJsonString;
Envelope2D envelope = new Envelope2D();
// Test Import from MultiLineString
-
- geoJsonString = "{\"type\": \"MultiLineString\", \"coordinates\": []}";
- polyline = (Polyline) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\":\"MultiLineString\",\"coordinates\":[], \"crs\" : {\"type\" : \"URL\", \"properties\" : {\"url\" : \"http://www.opengis.net/def/crs/EPSG/0/3857\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ polyline = (Polyline) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(polyline != null);
+ assertTrue(spatial_reference != null);
assertTrue(polyline.isEmpty());
- assertTrue(!polyline.hasAttribute(VertexDescription.Semantics.Z));
- assertTrue(!polyline.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(spatial_reference.getLatestID() == 3857);
- geoJsonString = "{\"type\": \"MultiLineString\", \"coordinates\": [[], [], [[10, 10, 5], [10, 20, 5], [20, 88, 5], [20, 10, 5]], [[12, 88, 3]], [], [[10, 10, 1], [12, 12, 1]], [], [[88, 60, 7], [60, 90, 7], [90, 90, 7]], [], [[70, 70, 7], [70, 80, 7], [80, 80, 7]], []]}";
- polyline = (Polyline) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"crs\" : {\"type\" : \"link\", \"properties\" : {\"href\" : \"www.spatialreference.org/ref/epsg/4309/\"}}, \"type\":\"MultiLineString\",\"coordinates\":[[], [], [[10, 10, 5], [10, 20, 5], [20, 88, 5], [20, 10, 5]], [[12, 88, 3]], [], [[10, 10, 1], [12, 12, 1]], [], [[88, 60, 7], [60, 90, 7], [90, 90, 7]], [], [[70, 70, 7], [70, 80, 7], [80, 80, 7]], []]}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ polyline = (Polyline) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(polyline != null);
polyline.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 90
- && envelope.ymin == 10 && envelope.ymax == 90);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 90 && envelope.ymin == 10 && envelope.ymax == 90);
assertTrue(polyline.getPointCount() == 14);
assertTrue(polyline.getPathCount() == 5);
- // assertTrue(!polyline.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(polyline.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(spatial_reference.getLatestID() == 4309);
+
+ geoJsonString = exporterGeoJson.execute(0, spatial_reference, polyline);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiLineString\",\"coordinates\":[[[10,10,5],[10,20,5],[20,88,5],[20,10,5]],[[12,88,3],[12,88,3]],[[10,10,1],[12,12,1]],[[88,60,7],[60,90,7],[90,90,7]],[[70,70,7],[70,80,7],[80,80,7]]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4309\"}}}"));
// Test Import LineString
- geoJsonString = "{\"type\": \"Linestring\", \"coordinates\": [[10, 10, 5], [10, 20, 5], [20, 20, 5], [20, 10, 5]]}";
- polyline = (Polyline) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\": \"LineString\", \"coordinates\": [[10, 10, 5], [10, 20, 5], [20, 20, 5], [20, 10, 5]]}";
+ polyline = (Polyline) (importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ assertTrue(polyline.getPointCount() == 4);
+ assertTrue(polyline.hasAttribute(VertexDescription.Semantics.Z));
+
+ geoJsonString = "{\"type\": \"LineString\", \"coordinates\": [[10, 10, 5], [10, 20, 5, 3], [20, 20, 5], [20, 10, 5]]}";
+ polyline = (Polyline) (importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry());
assertTrue(polyline.getPointCount() == 4);
- // assertTrue(polyline.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(polyline.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(polyline.hasAttribute(VertexDescription.Semantics.M));
- geoJsonString = "{\"type\": \"Linestring\", \"coordinates\": [[10, 10, 5], [10, 20, 5, 3], [20, 20, 5], [20, 10, 5]]}";
- polyline = (Polyline) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\":\"LineString\",\"coordinates\": [[10, 10, 5], [10, 20, 5], [20, 20, 5], [], [20, 10, 5]],\"crs\" : {\"type\" : \"link\", \"properties\" : {\"href\" : \"www.opengis.net/def/crs/EPSG/0/3857\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ polyline = (Polyline) (map_geometry.getGeometry());
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(polyline.getPointCount() == 4);
- // assertTrue(polyline.hasAttribute(VertexDescription.Semantics.Z));
- // assertTrue(polyline.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(spatial_reference.getLatestID() == 3857);
+ geoJsonString = exporterGeoJson.execute(0, spatial_reference, polyline);
+ assertTrue(geoJsonString.equals("{\"type\":\"LineString\",\"coordinates\":[[10,10,5],[10,20,5],[20,20,5],[20,10,5]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:3857\"}}}"));
+
+ geoJsonString = exporterGeoJson.execute(0, null, polyline);
+ assertTrue(geoJsonString.equals("{\"type\":\"LineString\",\"coordinates\":[[10,10,5],[10,20,5],[20,20,5],[20,10,5]],\"crs\":null}"));
}
@Test
- public static void testImportGeoJsonMultiPoint() throws JSONException {
- OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
-
+ public static void testImportGeoJsonMultiPoint() throws Exception {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ OperatorExportToGeoJson exporterGeoJson = (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToGeoJson);
+ MapGeometry map_geometry;
MultiPoint multipoint;
+ SpatialReference spatial_reference;
String geoJsonString;
Envelope2D envelope = new Envelope2D();
// Test Import from Multi_point
- geoJsonString = "{\"type\": \"MultiPoint\", \"coordinates\": []}";
- multipoint = (MultiPoint) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\":\"MultiPoint\",\"coordinates\":[]}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ multipoint = (MultiPoint) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(multipoint != null);
assertTrue(multipoint.isEmpty());
- assertTrue(!multipoint.hasAttribute(VertexDescription.Semantics.Z));
- assertTrue(!multipoint.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(spatial_reference.getLatestID() == 4326);
+
+ geoJsonString = exporterGeoJson.execute(0, null, multipoint);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPoint\",\"coordinates\":[],\"crs\":null}"));
multipoint = new MultiPoint();
- multipoint.add(118.15114354234563, 33.82234433423462345);
+ multipoint.add(118.15, 2);
multipoint.add(88, 88);
- multipoint = new MultiPoint();
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportPrecision16, SpatialReference.create(4269), multipoint);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPoint\",\"coordinates\":[[118.15,2],[88,88]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4269\"}}}"));
+
+ multipoint.setEmpty();
multipoint.add(88, 2);
multipoint.add(88, 88);
- geoJsonString = "{\"type\": \"Multipoint\", \"coordinates\": [[], [], [10, 88, 88, 33], [10, 20, 5, 33], [20, 20, 5, 33], [20, 10, 5, 33], [12, 12, 3, 33], [], [10, 10, 1, 33], [12, 12, 1, 33], [], [60, 60, 7, 33], [60, 90.1, 7, 33], [90, 90, 7, 33], [], [70, 70, 7, 33], [70, 80, 7, 33], [80, 80, 7, 33], []]}";
- multipoint = (MultiPoint) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = exporterGeoJson.execute(0, SpatialReference.create(102100), multipoint);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPoint\",\"coordinates\":[[88,2],[88,88]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:3857\"}}}"));
+
+ geoJsonString = "{\"type\":\"MultiPoint\",\"coordinates\":[[], [], [10, 88, 88, 33], [10, 20, 5, 33], [20, 20, 5, 33], [20, 10, 5, 33], [12, 12, 3, 33], [], [10, 10, 1, 33], [12, 12, 1, 33], [], [60, 60, 7, 33], [60, 90.1, 7, 33], [90, 90, 7, 33], [], [70, 70, 7, 33], [70, 80, 7, 33], [80, 80, 7, 33], []],\"crs\":{\"type\":\"OGC\",\"properties\":{\"urn\":\"urn:ogc:def:crs:OGC:1.3:CRS83\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ multipoint = (MultiPoint) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(multipoint != null);
- multipoint.queryEnvelope2D(envelope);
- // assertTrue(envelope.xmin == 10 && envelope.xmax == 90 &&
- // envelope.ymin == 10 && Math.abs(envelope.ymax - 90.1) <= 0.001);
assertTrue(multipoint.getPointCount() == 13);
- // assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
- // assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(spatial_reference.getLatestID() == 4269);
- geoJsonString = "{\"type\": \"Multipoint\", \"coordinates\": [[10, 88, 88, 33], [10, 20, 5, 33], [20, 20, 5, 33], [20, 10, 5, 33], [12, 12, 3, 33], [10, 10, 1, 33], [12, 12, 1, 33], [60, 60, 7, 33], [60, 90.1, 7, 33], [90, 90, 7, 33], [70, 70, 7, 33], [70, 80, 7, 33], [80, 80, 7, 33]]}";
- multipoint = (MultiPoint) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\":\"MultiPoint\",\"coordinates\": [[10, 88, 88, 33], [10, 20, 5, 33], [20, 20, 5, 33], [], [20, 10, 5, 33], [12, 12, 3, 33], [], [10, 10, 1, 33], [12, 12, 1, 33], [60, 60, 7, 33], [60, 90.1, 7, 33], [90, 90, 7, 33], [70, 70, 7, 33], [70, 80, 7, 33], [80, 80, 7, 33]]}";
+ multipoint = (MultiPoint) importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry();
assertTrue(multipoint != null);
- // assertTrue(envelope.xmin == 10 && envelope.xmax == 90 &&
- // envelope.ymin == 10 && ::fabs(envelope.ymax - 90.1) <= 0.001);
assertTrue(multipoint.getPointCount() == 13);
- // assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
- // assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(multipoint.hasAttribute(VertexDescription.Semantics.M));
+
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportPrecision15, null, multipoint);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPoint\",\"coordinates\":[[10,88,88,33],[10,20,5,33],[20,20,5,33],[20,10,5,33],[12,12,3,33],[10,10,1,33],[12,12,1,33],[60,60,7,33],[60,90.1,7,33],[90,90,7,33],[70,70,7,33],[70,80,7,33],[80,80,7,33]],\"crs\":null}"));
- geoJsonString = "{\"type\": \"Multipoint\", \"coordinates\": [[], [], [10, 10, 5, 33]]}";
- multipoint = (MultiPoint) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\":\"MultiPoint\",\"coordinates\":[[], [], [10, 10, 5, 33]]}";
+ multipoint = (MultiPoint) importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry();
+
+ geoJsonString = exporterGeoJson.execute(0, null, multipoint);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPoint\",\"coordinates\":[[10,10,5,33]],\"crs\":null}"));
}
@Test
- public static void testImportGeoJsonPolygon() throws JSONException {
- OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ public static void testImportGeoJsonPolygon() throws Exception {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
Polygon polygon;
String geoJsonString;
Envelope2D envelope = new Envelope2D();
// Test Import from Polygon
-
geoJsonString = "{\"type\": \"Polygon\", \"coordinates\": []}";
- polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Unknown,
- geoJsonString, null).getGeometry());
+ polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry());
assertTrue(polygon != null);
assertTrue(polygon.isEmpty());
assertTrue(!polygon.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(!polygon.hasAttribute(VertexDescription.Semantics.M));
geoJsonString = "{\"type\": \"Polygon\", \"coordinates\": [[], [[10, 10, 5], [20, 10, 5], [20, 20, 5], [10, 20, 5], [10, 10, 5]], [[12, 12, 3]], [], [[10, 10, 1], [12, 12, 1]]]}";
- polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Unknown,
- geoJsonString, null).getGeometry());
+ polygon = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry());
assertTrue(polygon != null);
polygon.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 20
- && envelope.ymin == 10 && envelope.ymax == 20);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 20 && envelope.ymin == 10 && envelope.ymax == 20);
assertTrue(polygon.getPointCount() == 8);
assertTrue(polygon.getPathCount() == 3);
- // assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(polygon.hasAttribute(VertexDescription.Semantics.Z));
- geoJsonString = "{\"type\": \"polygon\", \"coordinates\": [[[35, 10], [10, 20], [15, 40], [45, 45], [35, 10]], [[20, 30], [35, 35], [30, 20], [20, 30]]]}";
- Polygon polygon2 = (Polygon) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ geoJsonString = "{\"type\": \"Polygon\", \"coordinates\": [[[35, 10], [10, 20], [15, 40], [45, 45], [35, 10]], [[20, 30], [35, 35], [30, 20], [20, 30]]]}";
+ Polygon polygon2 = (Polygon) (importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry());
assertTrue(polygon2 != null);
}
@Test
- public static void testImportGeoJsonLineString() throws JSONException {
- OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ public static void testImportGeoJsonLineString() throws Exception {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
Polyline polyline;
String geoJsonString;
Envelope2D envelope = new Envelope2D();
// Test Import from LineString
-
geoJsonString = "{\"type\": \"LineString\", \"coordinates\": []}";
- polyline = (Polyline) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ polyline = (Polyline) (importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry());
assertTrue(polyline != null);
assertTrue(polyline.isEmpty());
assertTrue(!polyline.hasAttribute(VertexDescription.Semantics.Z));
assertTrue(!polyline.hasAttribute(VertexDescription.Semantics.M));
geoJsonString = "{\"type\": \"LineString\", \"coordinates\": [[10, 10, 5], [10, 20, 5], [20, 20, 5], [20, 10, 5]]}";
- polyline = (Polyline) (importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString, null).getGeometry());
+ polyline = (Polyline) (importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null).getGeometry());
assertTrue(polyline != null);
polyline.queryEnvelope2D(envelope);
- assertTrue(envelope.xmin == 10 && envelope.xmax == 20
- && envelope.ymin == 10 && envelope.ymax == 20);
+ assertTrue(envelope.xmin == 10 && envelope.xmax == 20 && envelope.ymin == 10 && envelope.ymax == 20);
assertTrue(polyline.getPointCount() == 4);
assertTrue(polyline.getPathCount() == 1);
- // assertTrue(!polyline.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(!polyline.hasAttribute(VertexDescription.Semantics.M));
}
@Test
- public static void testImportGeoJsonPoint() throws JSONException {
- OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
-
+ public static void testImportGeoJsonPoint() throws Exception {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ OperatorExportToGeoJson exporterGeoJson = (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToGeoJson);
+ MapGeometry map_geometry;
+ SpatialReference spatial_reference;
Point point;
String geoJsonString;
// Test Import from Point
+ geoJsonString = "{\"type\":\"Point\",\"coordinates\":[],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:3857\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ point = (Point) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
+ assertTrue(spatial_reference.getLatestID() == 3857);
- geoJsonString = "{\"type\": \"Point\", \"coordinates\": []}";
- point = (Point) (importerGeoJson.execute(0, Geometry.Type.Unknown,
- geoJsonString, null).getGeometry());
assertTrue(point != null);
assertTrue(point.isEmpty());
- assertTrue(!point.hasAttribute(VertexDescription.Semantics.Z));
- assertTrue(!point.hasAttribute(VertexDescription.Semantics.M));
- geoJsonString = "{\"type\": \"Point\", \"coordinates\": [30.1, 10.6, 5.1, 33.1]}";
- point = (Point) (importerGeoJson.execute(0, Geometry.Type.Unknown,
- geoJsonString, null).getGeometry());
+ geoJsonString = exporterGeoJson.execute(0, null, point);
+ assertTrue(geoJsonString.equals("{\"type\":\"Point\",\"coordinates\":[],\"crs\":null}"));
+
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportPreferMultiGeometry, null, point);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPoint\",\"coordinates\":[],\"crs\":null}"));
+
+ geoJsonString = "{\"type\":\"Point\",\"coordinates\":[30.1,10.6,5.1,33.1],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"urn:ogc:def:crs:ESRI::54051\"}}}";
+ map_geometry = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ point = (Point) map_geometry.getGeometry();
+ spatial_reference = map_geometry.getSpatialReference();
assertTrue(point != null);
- // assertTrue(point.hasAttribute(VertexDescription.Semantics.Z));
- // assertTrue(point.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(point.hasAttribute(VertexDescription.Semantics.Z));
+ assertTrue(point.hasAttribute(VertexDescription.Semantics.M));
+ assertTrue(spatial_reference.getLatestID() == 54051);
double x = point.getX();
double y = point.getY();
- // double z = point.getZ();
- // double m = point.getM();
+ double z = point.getZ();
+ double m = point.getM();
assertTrue(x == 30.1);
assertTrue(y == 10.6);
- // assertTrue(z == 5.1);
- // assertTrue(m == 33.1);
+ assertTrue(z == 5.1);
+ assertTrue(m == 33.1);
+
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportPrecision15, spatial_reference, point);
+ assertTrue(geoJsonString.equals("{\"type\":\"Point\",\"coordinates\":[30.1,10.6,5.1,33.1],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"ESRI:54051\"}}}"));
+
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportPrecision15, SpatialReference.create(4287), point);
+ assertTrue(geoJsonString.equals("{\"type\":\"Point\",\"coordinates\":[30.1,10.6,5.1,33.1],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4287\"}}}"));
+
+ geoJsonString = exporterGeoJson.execute(GeoJsonExportFlags.geoJsonExportPreferMultiGeometry | GeoJsonExportFlags.geoJsonExportPrecision15, null, point);
+ assertTrue(geoJsonString.equals("{\"type\":\"MultiPoint\",\"coordinates\":[[30.1,10.6,5.1,33.1]],\"crs\":null}"));
+ }
+
+ @Test
+ public static void testImportExportGeoJsonMalformed() {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ OperatorExportToGeoJson exporterGeoJson = (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToGeoJson);
+
+ String geoJsonString;
+
+ try {
+ geoJsonString = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[2,2,2],[3,3,3],[4,4,4],[2,2,2]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"Polygon\",\"coordinates\":[[2,2,2],[3,3,3],[4,4,4],[2,2,2]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"Polygon\",\"coordinates\":[[[2,2,2],[3,3,3],[4,4,4],[2,2,2]],2,4]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"MultiPoint\",\"coordinates\":[[[2,2,2],[3,3,3],[4,4,4],[2,2,2]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"LineString\",\"coordinates\":[[[2,2,2],[3,3,3],[4,4,4],[2,2,2]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"MultiPoint\",\"coordinates\":[[2,2,2],[3,3,3],[4,4,4],[2,2,2],[[]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[2,2,2],[3,3,3],[4,4,4],[2,2,2],[[]]]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[2,2,2],[3,3,3],[4,4,4],[2,2,2]],[1,1,1],[2,2,2],[3,3,3],[1,1,1]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"Polygon\",\"coordinates\":[[[2,2,2],[3,3,3],[4,4,4],[2,2,2]],[1,1,1],[2,2,2],[3,3,3],[1,1,1]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[[]]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[{}]]]}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
+
+ try {
+ geoJsonString = "{\"type\":\"Point\",\"coordinates\":[30.1,10.6,[],33.1],\"crs\":\"EPSG:3857\"}";
+ importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString, null);
+ assertTrue(false);
+ } catch (Exception e) {
+ }
}
@Test
- public static void testImportGeoJsonSpatialReference() throws JSONException {
- OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromGeoJson);
+ public static void testImportGeoJsonSpatialReference() throws Exception {
+ OperatorImportFromGeoJson importerGeoJson = (OperatorImportFromGeoJson) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ImportFromGeoJson);
String geoJsonString4326;
String geoJsonString3857;
// Test Import from Point
-
geoJsonString4326 = "{\"type\": \"Point\", \"coordinates\": [3.0, 5.0], \"crs\": \"EPSG:4326\"}";
geoJsonString3857 = "{\"type\": \"Point\", \"coordinates\": [3.0, 5.0], \"crs\": \"EPSG:3857\"}";
- MapGeometry mapGeometry4326 = importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString4326, null);
- MapGeometry mapGeometry3857 = importerGeoJson.execute(0,
- Geometry.Type.Unknown, geoJsonString3857, null);
+ MapGeometry mapGeometry4326 = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString4326, null);
+ MapGeometry mapGeometry3857 = importerGeoJson.execute(0, Geometry.Type.Unknown, geoJsonString3857, null);
assertTrue(mapGeometry4326.equals(mapGeometry3857) == false);
- assertTrue(mapGeometry4326.getGeometry().equals(
- mapGeometry3857.getGeometry()));
+ assertTrue(mapGeometry4326.getGeometry().equals(mapGeometry3857.getGeometry()));
}
+ @Test
+ public void testZeroRingWkb() {
+ //https://github.com/Esri/geometry-api-java/issues/275
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 10);
+ poly.lineTo(0, 10);
+ poly.addEnvelope(new Envelope(1, 1, 3, 3), false);
+
+ ByteBuffer bb = OperatorExportToWkb.local().execute(0, poly, null);
+ Geometry res = OperatorImportFromWkb.local().execute(0, Geometry.Type.Unknown, bb, null);
+ assertTrue(res.equals(poly));
+ }
+
public static Polygon makePolygon() {
Polygon poly = new Polygon();
poly.startPath(0, 0);
diff --git a/src/test/java/com/esri/core/geometry/TestIndexHashTable.java b/src/test/java/com/esri/core/geometry/TestIndexHashTable.java
new file mode 100644
index 00000000..36ec75ac
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestIndexHashTable.java
@@ -0,0 +1,72 @@
+package com.esri.core.geometry;
+import org.junit.Test;
+import junit.framework.TestCase;
+public class TestIndexHashTable extends TestCase{
+ @Test
+ public void testAddElement() {
+ IndexHashTable.HashFunction hashFunction = new IndexHashTable.HashFunction() {
+ @Override
+ public int getHash(int element) {
+ return element % 10; // A simple hash function for testing
+ }
+
+ @Override
+ public boolean equal(int element1, int element2) {
+ return element1 == element2;
+ }
+
+ @Override
+ public int getHash(Object elementDescriptor) {
+ return ((Integer) elementDescriptor) % 10;
+ }
+
+ @Override
+ public boolean equal(Object elementDescriptor, int element) {
+ return ((Integer) elementDescriptor) == element;
+ }
+ };
+
+ IndexHashTable hashTable = new IndexHashTable(10, hashFunction);
+
+ int element1 = 5;
+
+ int node1 = hashTable.addElement(element1);
+
+ assertEquals(node1, hashTable.findNode(element1));
+ }
+
+ @Test
+ public void testDeleteElement() {
+ IndexHashTable.HashFunction hashFunction = new IndexHashTable.HashFunction() {
+ @Override
+ public int getHash(int element) {
+ return element % 10; // A simple hash function for testing
+ }
+
+ @Override
+ public boolean equal(int element1, int element2) {
+ return element1 == element2;
+ }
+
+ @Override
+ public int getHash(Object elementDescriptor) {
+ return ((Integer) elementDescriptor) % 10;
+ }
+
+ @Override
+ public boolean equal(Object elementDescriptor, int element) {
+ return ((Integer) elementDescriptor) == element;
+ }
+ };
+
+ IndexHashTable hashTable = new IndexHashTable(10, hashFunction);
+
+ int element1 = 5;
+
+ int node1 = hashTable.addElement(element1);
+
+ hashTable.deleteElement(element1);
+ assertEquals(IndexHashTable.nullNode(), hashTable.findNode(element1));
+ }
+
+}
diff --git a/unittest/com/esri/core/geometry/TestInterpolateAttributes.java b/src/test/java/com/esri/core/geometry/TestInterpolateAttributes.java
similarity index 90%
rename from unittest/com/esri/core/geometry/TestInterpolateAttributes.java
rename to src/test/java/com/esri/core/geometry/TestInterpolateAttributes.java
index de462a02..f20f3063 100644
--- a/unittest/com/esri/core/geometry/TestInterpolateAttributes.java
+++ b/src/test/java/com/esri/core/geometry/TestInterpolateAttributes.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
diff --git a/unittest/com/esri/core/geometry/TestIntersect2.java b/src/test/java/com/esri/core/geometry/TestIntersect2.java
similarity index 92%
rename from unittest/com/esri/core/geometry/TestIntersect2.java
rename to src/test/java/com/esri/core/geometry/TestIntersect2.java
index f5276d69..36860635 100644
--- a/unittest/com/esri/core/geometry/TestIntersect2.java
+++ b/src/test/java/com/esri/core/geometry/TestIntersect2.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import com.esri.core.geometry.Geometry.Type;
@@ -358,7 +382,6 @@ public void testMultiPointAndMultiPoint3() {
SpatialReference.create(4326));
} catch (Exception ex) {
noException = 0;
- System.out.println("err: " + ex.getMessage());
}
assertEquals(noException, 1);
assertTrue(intersectGeom.isEmpty());
diff --git a/unittest/com/esri/core/geometry/TestIntersection.java b/src/test/java/com/esri/core/geometry/TestIntersection.java
similarity index 87%
rename from unittest/com/esri/core/geometry/TestIntersection.java
rename to src/test/java/com/esri/core/geometry/TestIntersection.java
index 68b0766b..eb6a2a73 100644
--- a/unittest/com/esri/core/geometry/TestIntersection.java
+++ b/src/test/java/com/esri/core/geometry/TestIntersection.java
@@ -1,8 +1,35 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
+
import org.junit.Test;
+import com.esri.core.geometry.PolygonUtils.PiPResult;
+
//import java.util.Random;
public class TestIntersection extends TestCase {
@@ -991,5 +1018,94 @@ public void testUnionTickTock() {
Geometry result2 = res.next();
assertTrue(result.equals(result2));
}
-
+
+ @Test
+ public void testIntersectionIssueLinePoly1() {
+ String wkt1 = new String("polygon((0 0, 10 0, 10 10, 0 10, 0 0))");
+ String wkt2 = new String("linestring(9 5, 10 5, 9 4, 8 3)");
+ Geometry g1 = OperatorImportFromWkt.local().execute(0, Geometry.Type.Unknown, wkt1, null);
+ Geometry g2 = OperatorImportFromWkt.local().execute(0, Geometry.Type.Unknown, wkt2, null);
+ Geometry res = OperatorIntersection.local().execute(g1, g2, null, null);
+ assertTrue(((Polyline)res).getPathCount() == 1);
+ assertTrue(((Polyline)res).getPointCount() == 4);
+ }
+
+ @Test
+ public void testSharedEdgeIntersection_13()
+ {
+ String s1 = "{\"rings\":[[[0.099604024000029767,0.2107958250000479],[0.14626826900007472,0.2107958250000479],[0.14626826900007472,0.18285316400005058],[0.099604024000029767,0.18285316400005058],[0.099604024000029767,0.2107958250000479]]]}";
+ String s2 = "{\"paths\":[[[0.095692051000071388,0.15910190100004229],[0.10324853600002371,0.18285316400004228],[0.12359292700006108,0.18285316400004228],[0.12782611200003657,0.1705583920000322],[0.13537063000007138,0.18285316400004228]]]}";
+
+ Polygon polygon = (Polygon)TestCommonMethods.fromJson(s1).getGeometry();
+ Polyline polyline = (Polyline)TestCommonMethods.fromJson(s2).getGeometry();
+ SpatialReference sr = SpatialReference.create(4326);
+
+ Geometry g = OperatorIntersection.local().execute(polygon, polyline, sr, null);
+ assertTrue(!g.isEmpty());
+ }
+
+ @Test
+ public void testIntersectionIssue2() {
+ String s1 = "{\"rings\":[[[-97.174860352323378,48.717174479818425],[-97.020624513410553,58.210155436624177],[-94.087641114245969,58.210155436624177],[-94.087641114245969,48.639781902013226],[-97.174860352323378,48.717174479818425]]]}";
+ String s2 = "{\"rings\":[[[-94.08764111399995,52.68342763000004],[-94.08764111399995,56.835188018000053],[-90.285921520999977,62.345706350000057],[-94.08764111399995,52.68342763000004]]]}";
+
+ Polygon polygon1 = (Polygon)TestCommonMethods.fromJson(s1).getGeometry();
+ Polygon polygon2 = (Polygon)TestCommonMethods.fromJson(s2).getGeometry();
+ SpatialReference sr = SpatialReference.create(4326);
+
+ GeometryCursor res = OperatorIntersection.local().execute(new SimpleGeometryCursor(polygon1), new SimpleGeometryCursor(polygon2), sr, null, 2);
+ Geometry g = res.next();
+ assertTrue(g != null);
+ assertTrue(!g.isEmpty());
+ Geometry g2 = res.next();
+ assertTrue(g2 == null);
+
+ String ss = "{\"paths\":[[[-94.08764111412296,52.68342763000004],[-94.08764111410767,56.83518801800005]]]}";
+ Polyline polyline = (Polyline)TestCommonMethods.fromJson(ss).getGeometry();
+ boolean eq = OperatorEquals.local().execute(g, polyline, sr, null);
+ assertTrue(eq);
+ }
+
+ /*
+ Point2D uniqueIntersectionPointOfNonDisjointGeometries(Geometry g1, Geometry g2, SpatialReference sr) {
+ Geometry g1Test = g1;
+ boolean g1Polygon = g1.getType() == Geometry.Type.Polygon;
+ boolean g2Polygon = g2.getType() == Geometry.Type.Polygon;
+
+ if (g1Polygon || g2Polygon)
+ {
+ if (g1Polygon) {
+ Point2D p = getFirstPoint(g2);
+ if (PolygonUtils.isPointInPolygon2D((Polygon)g1, p, 0) != PiPResult.PiPOutside)
+ return p;
+ }
+ if (g2Polygon) {
+ Point2D p = getFirstPoint(g1);
+ if (PolygonUtils.isPointInPolygon2D((Polygon)g2, p, 0) != PiPResult.PiPOutside)
+ return p;
+ }
+ }
+
+ if (g1Polygon)
+ {
+ Polyline polyline = new Polyline();
+ polyline.add((MultiPath)g1, false);
+ g1Test = polyline;
+ }
+ Geometry g2Test = g2;
+ if (g2Polygon)
+ {
+ Polyline polyline = new Polyline();
+ polyline.add((MultiPath)g2, false);
+ g2Test = polyline;
+ }
+
+ GeometryCursor gc = OperatorIntersection.local().execute(new SimpleGeometryCursor(g1Test), new SimpleGeometryCursor(g2Test), sr, null, 3);
+ for (Geometry res = gc.next(); res != null; res = gc.next()) {
+ return getFirstPoint(res);
+ }
+
+ throw new GeometryException("internal error");
+ }*/
+
}
diff --git a/unittest/com/esri/core/geometry/TestIntervalTree.java b/src/test/java/com/esri/core/geometry/TestIntervalTree.java
similarity index 91%
rename from unittest/com/esri/core/geometry/TestIntervalTree.java
rename to src/test/java/com/esri/core/geometry/TestIntervalTree.java
index 0b12d678..4c0cde97 100644
--- a/unittest/com/esri/core/geometry/TestIntervalTree.java
+++ b/src/test/java/com/esri/core/geometry/TestIntervalTree.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import java.util.ArrayList;
diff --git a/src/test/java/com/esri/core/geometry/TestJSONUtils.java b/src/test/java/com/esri/core/geometry/TestJSONUtils.java
new file mode 100644
index 00000000..86a29aff
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestJSONUtils.java
@@ -0,0 +1,47 @@
+package com.esri.core.geometry;
+
+import org.junit.Test;
+import junit.framework.TestCase;
+import org.mockito.Mockito;
+public class TestJSONUtils extends TestCase{
+
+ @Test
+ public void testReadDoubleWithFloatValue() {
+ JsonReader parser = Mockito.mock(JsonReader.class);
+ Mockito.when(parser.currentToken()).thenReturn(JsonReader.Token.VALUE_NUMBER_FLOAT);
+ Mockito.when(parser.currentDoubleValue()).thenReturn(3.14);
+
+ double result = JSONUtils.readDouble(parser);
+ assertEquals(3.14, result, 0.0001);
+ }
+
+ @Test
+ public void testReadDoubleWithIntValue() {
+ JsonReader parser = Mockito.mock(JsonReader.class);
+ Mockito.when(parser.currentToken()).thenReturn(JsonReader.Token.VALUE_NUMBER_INT);
+ Mockito.when(parser.currentIntValue()).thenReturn(42);
+
+ double result = JSONUtils.readDouble(parser);
+ assertEquals(42.0, result, 0.0001);
+ }
+
+ @Test
+ public void testReadDoubleWithNullValue() {
+ JsonReader parser = Mockito.mock(JsonReader.class);
+ Mockito.when(parser.currentToken()).thenReturn(JsonReader.Token.VALUE_NULL);
+
+ double result = JSONUtils.readDouble(parser);
+ assertTrue(Double.isNaN(result));
+ }
+
+ @Test
+ public void testReadDoubleWithNaNString() {
+ JsonReader parser = Mockito.mock(JsonReader.class);
+ Mockito.when(parser.currentToken()).thenReturn(JsonReader.Token.VALUE_STRING);
+ Mockito.when(parser.currentString()).thenReturn("NaN");
+
+ double result = JSONUtils.readDouble(parser);
+ assertTrue(Double.isNaN(result));
+ }
+
+}
diff --git a/unittest/com/esri/core/geometry/TestJSonGeometry.java b/src/test/java/com/esri/core/geometry/TestJSonGeometry.java
similarity index 59%
rename from unittest/com/esri/core/geometry/TestJSonGeometry.java
rename to src/test/java/com/esri/core/geometry/TestJSonGeometry.java
index 571a103e..62342524 100644
--- a/unittest/com/esri/core/geometry/TestJSonGeometry.java
+++ b/src/test/java/com/esri/core/geometry/TestJSonGeometry.java
@@ -1,47 +1,72 @@
-package com.esri.core.geometry;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestJSonGeometry extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public void testGetSpatialReferenceFor4326() {
- String completeStr = "GEOGCS[\"GCS_Sphere\",DATUM[\"D_Sphere\","
- + "SPHEROID[\"Sphere\",6371000.0,0.0]],PRIMEM[\"Greenwich\",0.0],"
- + "UNIT[\"Degree\",0.0174532925199433]]";
-
- // 4326 GCS_WGS_1984
- SpatialReference sr = SpatialReference.create(completeStr);
- assertNotNull(sr);
- }
-
}
-
-final class HashMapClassForTesting {
- static Map SR_WKI_WKTs = new HashMap() {
- /**
- * added to get rid of warning
- */
- private static final long serialVersionUID = 8630934425353750539L;
-
- {
- put(4035,
- "GEOGCS[\"GCS_Sphere\",DATUM[\"D_Sphere\","
- + "SPHEROID[\"Sphere\",6371000.0,0.0]],PRIMEM[\"Greenwich\",0.0],"
- + "UNIT[\"Degree\",0.0174532925199433]]");
- }
- };
-}
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class TestJSonGeometry extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testGetSpatialReferenceFor4326() {
+ String completeStr = "GEOGCS[\"GCS_Sphere\",DATUM[\"D_Sphere\","
+ + "SPHEROID[\"Sphere\",6371000.0,0.0]],PRIMEM[\"Greenwich\",0.0],"
+ + "UNIT[\"Degree\",0.0174532925199433]]";
+
+ // 4326 GCS_WGS_1984
+ SpatialReference sr = SpatialReference.create(completeStr);
+ assertNotNull(sr);
+ }
+
+}
+
+final class HashMapClassForTesting {
+ static Map SR_WKI_WKTs = new HashMap() {
+ /**
+ * added to get rid of warning
+ */
+ private static final long serialVersionUID = 8630934425353750539L;
+
+ {
+ put(4035,
+ "GEOGCS[\"GCS_Sphere\",DATUM[\"D_Sphere\","
+ + "SPHEROID[\"Sphere\",6371000.0,0.0]],PRIMEM[\"Greenwich\",0.0],"
+ + "UNIT[\"Degree\",0.0174532925199433]]");
+ }
+ };
+}
diff --git a/unittest/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java b/src/test/java/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java
similarity index 76%
rename from unittest/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java
rename to src/test/java/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java
index 243f7c26..a6ac4d96 100644
--- a/unittest/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java
+++ b/src/test/java/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java
@@ -1,123 +1,148 @@
-package com.esri.core.geometry;
-
-import java.io.IOException;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestJSonToGeomFromWkiOrWkt_CR177613 extends TestCase {
- JsonFactory factory = new JsonFactory();
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public void testPolygonWithEmptyWKT_NoWKI() throws JsonParseException,
- IOException {
- String jsonStringPg = "{ \"rings\" :[ [ [-97.06138,32.837], [-97.06133,32.836], "
- + "[-97.06124,32.834], [-97.06127,32.832], [-97.06138,32.837] ], "
- + "[ [-97.06326,32.759], [-97.06298,32.755], [-97.06153,32.749], [-97.06326,32.759] ]], "
- + "\"spatialReference\" : {\"wkt\" : \"\"}}";
- JsonParser jsonParserPg = factory.createJsonParser(jsonStringPg);
- jsonParserPg.nextToken();
-
- MapGeometry mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg);
- Utils.showProjectedGeometryInfo(mapGeom);
- SpatialReference sr = mapGeom.getSpatialReference();
- assertTrue(sr == null);
- }
-
- @Test
- public void testOnlyWKI() throws JsonParseException, IOException {
- String jsonStringSR = "{\"wkid\" : 4326}";
- JsonParser jsonParserSR = factory.createJsonParser(jsonStringSR);
- jsonParserSR.nextToken();
-
- MapGeometry mapGeom = GeometryEngine.jsonToGeometry(jsonParserSR);
- Utils.showProjectedGeometryInfo(mapGeom);
- SpatialReference sr = mapGeom.getSpatialReference();
- assertTrue(sr == null);
- }
-
- @Test
- public void testMP2onCR175871() throws Exception {
- Polygon pg = new Polygon();
- pg.startPath(-50, 10);
- pg.lineTo(-50, 12);
- pg.lineTo(-45, 12);
- pg.lineTo(-45, 10);
-
- Polygon pg1 = new Polygon();
- pg1.startPath(-45, 10);
- pg1.lineTo(-40, 10);
- pg1.lineTo(-40, 8);
- pg.add(pg1, false);
-
- try {
- String jSonStr = GeometryEngine.geometryToJson(4326, pg);
- JsonFactory jf = new JsonFactory();
-
- JsonParser jp = jf.createJsonParser(jSonStr);
- jp.nextToken();
- MapGeometry mg = GeometryEngine.jsonToGeometry(jp);
- Geometry gm = mg.getGeometry();
- assertEquals(Geometry.Type.Polygon, gm.getType());
-
- Polygon pgNew = (Polygon) gm;
-
- assertEquals(pgNew.getPathCount(), pg.getPathCount());
- assertEquals(pgNew.getPointCount(), pg.getPointCount());
- assertEquals(pgNew.getSegmentCount(), pg.getSegmentCount());
-
- assertEquals(pgNew.getPoint(0).getX(), pg.getPoint(0).getX(),
- 0.000000001);
- assertEquals(pgNew.getPoint(1).getX(), pg.getPoint(1).getX(),
- 0.000000001);
- assertEquals(pgNew.getPoint(2).getX(), pg.getPoint(2).getX(),
- 0.000000001);
- assertEquals(pgNew.getPoint(3).getX(), pg.getPoint(3).getX(),
- 0.000000001);
-
- assertEquals(pgNew.getPoint(0).getY(), pg.getPoint(0).getY(),
- 0.000000001);
- assertEquals(pgNew.getPoint(1).getY(), pg.getPoint(1).getY(),
- 0.000000001);
- assertEquals(pgNew.getPoint(2).getY(), pg.getPoint(2).getY(),
- 0.000000001);
- assertEquals(pgNew.getPoint(3).getY(), pg.getPoint(3).getY(),
- 0.000000001);
- } catch (Exception ex) {
- String err = ex.getMessage();
- System.out.print(err);
- throw ex;
- }
- }
-
- public static int fromJsonToWkid(JsonParser parser)
- throws JsonParseException, IOException {
- int wkid = 0;
- if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
- return 0;
- }
-
- while (parser.nextToken() != JsonToken.END_OBJECT) {
- String fieldName = parser.getCurrentName();
-
- if ("wkid".equals(fieldName)) {
- parser.nextToken();
- wkid = parser.getIntValue();
- }
- }
- return wkid;
- }
-}
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+
+public class TestJSonToGeomFromWkiOrWkt_CR177613 extends TestCase {
+ JsonFactory factory = new JsonFactory();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testPolygonWithEmptyWKT_NoWKI() throws JsonParseException,
+ IOException {
+ String jsonStringPg = "{ \"rings\" :[ [ [-97.06138,32.837], [-97.06133,32.836], "
+ + "[-97.06124,32.834], [-97.06127,32.832], [-97.06138,32.837] ], "
+ + "[ [-97.06326,32.759], [-97.06298,32.755], [-97.06153,32.749], [-97.06326,32.759] ]], "
+ + "\"spatialReference\" : {\"wkt\" : \"\"}}";
+ JsonParser jsonParserPg = factory.createParser(jsonStringPg);
+ jsonParserPg.nextToken();
+
+ MapGeometry mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg);
+ Utils.showProjectedGeometryInfo(mapGeom);
+ SpatialReference sr = mapGeom.getSpatialReference();
+ assertTrue(sr == null);
+ }
+
+ @Test
+ public void testOnlyWKI() throws JsonParseException, IOException {
+ String jsonStringSR = "{\"wkid\" : 4326}";
+ JsonParser jsonParserSR = factory.createJsonParser(jsonStringSR);
+ jsonParserSR.nextToken();
+
+ MapGeometry mapGeom = GeometryEngine.jsonToGeometry(jsonParserSR);
+ Utils.showProjectedGeometryInfo(mapGeom);
+ SpatialReference sr = mapGeom.getSpatialReference();
+ assertTrue(sr == null);
+ }
+
+ @Test
+ public void testMP2onCR175871() throws Exception {
+ Polygon pg = new Polygon();
+ pg.startPath(-50, 10);
+ pg.lineTo(-50, 12);
+ pg.lineTo(-45, 12);
+ pg.lineTo(-45, 10);
+
+ Polygon pg1 = new Polygon();
+ pg1.startPath(-45, 10);
+ pg1.lineTo(-40, 10);
+ pg1.lineTo(-40, 8);
+ pg.add(pg1, false);
+
+ try {
+ String jSonStr = GeometryEngine.geometryToJson(4326, pg);
+ JsonFactory jf = new JsonFactory();
+
+ JsonParser jp = jf.createJsonParser(jSonStr);
+ jp.nextToken();
+ MapGeometry mg = GeometryEngine.jsonToGeometry(jp);
+ Geometry gm = mg.getGeometry();
+ assertEquals(Geometry.Type.Polygon, gm.getType());
+
+ Polygon pgNew = (Polygon) gm;
+
+ assertEquals(pgNew.getPathCount(), pg.getPathCount());
+ assertEquals(pgNew.getPointCount(), pg.getPointCount());
+ assertEquals(pgNew.getSegmentCount(), pg.getSegmentCount());
+
+ assertEquals(pgNew.getPoint(0).getX(), pg.getPoint(0).getX(),
+ 0.000000001);
+ assertEquals(pgNew.getPoint(1).getX(), pg.getPoint(1).getX(),
+ 0.000000001);
+ assertEquals(pgNew.getPoint(2).getX(), pg.getPoint(2).getX(),
+ 0.000000001);
+ assertEquals(pgNew.getPoint(3).getX(), pg.getPoint(3).getX(),
+ 0.000000001);
+
+ assertEquals(pgNew.getPoint(0).getY(), pg.getPoint(0).getY(),
+ 0.000000001);
+ assertEquals(pgNew.getPoint(1).getY(), pg.getPoint(1).getY(),
+ 0.000000001);
+ assertEquals(pgNew.getPoint(2).getY(), pg.getPoint(2).getY(),
+ 0.000000001);
+ assertEquals(pgNew.getPoint(3).getY(), pg.getPoint(3).getY(),
+ 0.000000001);
+ } catch (Exception ex) {
+ String err = ex.getMessage();
+ System.out.print(err);
+ throw ex;
+ }
+ }
+
+ public static int fromJsonToWkid(JsonParser parser)
+ throws JsonParseException, IOException {
+ int wkid = 0;
+ if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
+ return 0;
+ }
+
+ while (parser.nextToken() != JsonToken.END_OBJECT) {
+ String fieldName = parser.getCurrentName();
+
+ if ("wkid".equals(fieldName)) {
+ parser.nextToken();
+ wkid = parser.getIntValue();
+ }
+ }
+ return wkid;
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestJsonParser.java b/src/test/java/com/esri/core/geometry/TestJsonParser.java
similarity index 63%
rename from unittest/com/esri/core/geometry/TestJsonParser.java
rename to src/test/java/com/esri/core/geometry/TestJsonParser.java
index 9c22d49a..96f6343c 100644
--- a/unittest/com/esri/core/geometry/TestJsonParser.java
+++ b/src/test/java/com/esri/core/geometry/TestJsonParser.java
@@ -1,663 +1,575 @@
-package com.esri.core.geometry;
-
-import java.io.IOException;
-import junit.framework.TestCase;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestJsonParser extends TestCase {
- JsonFactory factory = new JsonFactory();
- SpatialReference spatialReferenceWebMerc1 = SpatialReference.create(102100);
- SpatialReference spatialReferenceWebMerc2 = SpatialReference
- .create(spatialReferenceWebMerc1.getLatestID());
- SpatialReference spatialReferenceWGS84 = SpatialReference.create(4326);
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public void test3DPoint() throws JsonParseException, IOException {
- String jsonString3DPt = "{\"x\" : -118.15, \"y\" : 33.80, \"z\" : 10.0, \"spatialReference\" : {\"wkid\" : 4326}}";
-
- JsonParser jsonParser3DPt = factory.createJsonParser(jsonString3DPt);
- MapGeometry point3DMP = GeometryEngine.jsonToGeometry(jsonParser3DPt);
- assertTrue(-118.15 == ((Point) point3DMP.getGeometry()).getX());
- assertTrue(33.80 == ((Point) point3DMP.getGeometry()).getY());
- // FIXME add 3D support
- // assertTrue(10.0 == ((Point)point3DMP.getGeometry()).getZ());
- assertTrue(spatialReferenceWGS84.getID() == point3DMP
- .getSpatialReference().getID());
- }
-
- @Test
- public void test3DPoint1() throws JsonParseException, IOException {
- Point point1 = new Point(10.0, 20.0);
- Point pointEmpty = new Point();
- {
- JsonParser pointWebMerc1Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWebMerc1, point1));
- MapGeometry pointWebMerc1MP = GeometryEngine
- .jsonToGeometry(pointWebMerc1Parser);
- assertTrue(point1.getX() == ((Point) pointWebMerc1MP.getGeometry())
- .getX());
- assertTrue(point1.getY() == ((Point) pointWebMerc1MP.getGeometry())
- .getY());
- int srIdOri = spatialReferenceWebMerc1.getID();
- int srIdAfter = pointWebMerc1MP.getSpatialReference().getID();
- assertTrue(srIdOri == srIdAfter || srIdAfter == 3857);
-
- pointWebMerc1Parser = factory.createJsonParser(GeometryEngine
- .geometryToJson(null, point1));
- pointWebMerc1MP = GeometryEngine
- .jsonToGeometry(pointWebMerc1Parser);
- assertTrue(null == pointWebMerc1MP.getSpatialReference());
-
- String pointEmptyString = GeometryEngine.geometryToJson(
- spatialReferenceWebMerc1, pointEmpty);
- pointWebMerc1Parser = factory.createJsonParser(pointEmptyString);
- // FIXME
- pointWebMerc1MP = GeometryEngine
- .jsonToGeometry(pointWebMerc1Parser);
- assertTrue(pointWebMerc1MP.getGeometry().isEmpty());
- int srIdOri2 = spatialReferenceWebMerc1.getID();
- int srIdAfter2 = pointWebMerc1MP.getSpatialReference().getID();
- assertTrue(srIdOri2 == srIdAfter2 || srIdAfter2 == 3857);
- }
- }
-
- @Test
- public void test3DPoint2() throws JsonParseException, IOException {
- {
- Point point1 = new Point(10.0, 20.0);
- JsonParser pointWebMerc2Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWebMerc2, point1));
- MapGeometry pointWebMerc2MP = GeometryEngine
- .jsonToGeometry(pointWebMerc2Parser);
- assertTrue(point1.getX() == ((Point) pointWebMerc2MP.getGeometry())
- .getX());
- assertTrue(point1.getY() == ((Point) pointWebMerc2MP.getGeometry())
- .getY());
- assertTrue(spatialReferenceWebMerc2.getLatestID() == pointWebMerc2MP
- .getSpatialReference().getLatestID());
- }
- }
-
- @Test
- public void test3DPoint3() throws JsonParseException, IOException {
- {
- Point point1 = new Point(10.0, 20.0);
- JsonParser pointWgs84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, point1));
- MapGeometry pointWgs84MP = GeometryEngine
- .jsonToGeometry(pointWgs84Parser);
- assertTrue(point1.getX() == ((Point) pointWgs84MP.getGeometry())
- .getX());
- assertTrue(point1.getY() == ((Point) pointWgs84MP.getGeometry())
- .getY());
- assertTrue(spatialReferenceWGS84.getID() == pointWgs84MP
- .getSpatialReference().getID());
- }
- }
-
- @Test
- public void testMultiPoint() throws JsonParseException, IOException {
- MultiPoint multiPoint1 = new MultiPoint();
- multiPoint1.add(-97.06138, 32.837);
- multiPoint1.add(-97.06133, 32.836);
- multiPoint1.add(-97.06124, 32.834);
- multiPoint1.add(-97.06127, 32.832);
-
- {
- JsonParser mPointWgs84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, multiPoint1));
- MapGeometry mPointWgs84MP = GeometryEngine
- .jsonToGeometry(mPointWgs84Parser);
- assertTrue(multiPoint1.getPointCount() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPointCount());
- assertTrue(multiPoint1.getPoint(0).getX() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(0).getX());
- assertTrue(multiPoint1.getPoint(0).getY() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(0).getY());
- int lastIndex = multiPoint1.getPointCount() - 1;
- assertTrue(multiPoint1.getPoint(lastIndex).getX() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(lastIndex).getX());
- assertTrue(multiPoint1.getPoint(lastIndex).getY() == ((MultiPoint) mPointWgs84MP
- .getGeometry()).getPoint(lastIndex).getY());
-
- assertTrue(spatialReferenceWGS84.getID() == mPointWgs84MP
- .getSpatialReference().getID());
-
- MultiPoint mPointEmpty = new MultiPoint();
- String mPointEmptyString = GeometryEngine.geometryToJson(
- spatialReferenceWGS84, mPointEmpty);
- mPointWgs84Parser = factory.createJsonParser(mPointEmptyString);
-
- mPointWgs84MP = GeometryEngine.jsonToGeometry(mPointWgs84Parser);
- assertTrue(mPointWgs84MP.getGeometry().isEmpty());
- assertTrue(spatialReferenceWGS84.getID() == mPointWgs84MP
- .getSpatialReference().getID());
-
- }
- }
-
- @Test
- public void testPolyline() throws JsonParseException, IOException {
- Polyline polyline = new Polyline();
- polyline.startPath(-97.06138, 32.837);
- polyline.lineTo(-97.06133, 32.836);
- polyline.lineTo(-97.06124, 32.834);
- polyline.lineTo(-97.06127, 32.832);
-
- polyline.startPath(-97.06326, 32.759);
- polyline.lineTo(-97.06298, 32.755);
-
- {
- JsonParser polylinePathsWgs84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, polyline));
- MapGeometry mPolylineWGS84MP = GeometryEngine
- .jsonToGeometry(polylinePathsWgs84Parser);
-
- assertTrue(polyline.getPointCount() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPointCount());
- assertTrue(polyline.getPoint(0).getX() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(0).getX());
- assertTrue(polyline.getPoint(0).getY() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(0).getY());
-
- assertTrue(polyline.getPathCount() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPathCount());
- assertTrue(polyline.getSegmentCount() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getSegmentCount());
- assertTrue(polyline.getSegmentCount(0) == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getSegmentCount(0));
- assertTrue(polyline.getSegmentCount(1) == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getSegmentCount(1));
-
- int lastIndex = polyline.getPointCount() - 1;
- assertTrue(polyline.getPoint(lastIndex).getX() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(lastIndex).getX());
- assertTrue(polyline.getPoint(lastIndex).getY() == ((Polyline) mPolylineWGS84MP
- .getGeometry()).getPoint(lastIndex).getY());
-
- assertTrue(spatialReferenceWGS84.getID() == mPolylineWGS84MP
- .getSpatialReference().getID());
-
- Polyline emptyPolyline = new Polyline();
- String emptyString = GeometryEngine.geometryToJson(
- spatialReferenceWGS84, emptyPolyline);
- mPolylineWGS84MP = GeometryEngine.jsonToGeometry(factory
- .createJsonParser(emptyString));
- assertTrue(mPolylineWGS84MP.getGeometry().isEmpty());
- assertTrue(spatialReferenceWGS84.getID() == mPolylineWGS84MP
- .getSpatialReference().getID());
- }
- }
-
- @Test
- public void testPolygon() throws JsonParseException, IOException {
- Polygon polygon = new Polygon();
- polygon.startPath(-97.06138, 32.837);
- polygon.lineTo(-97.06133, 32.836);
- polygon.lineTo(-97.06124, 32.834);
- polygon.lineTo(-97.06127, 32.832);
-
- polygon.startPath(-97.06326, 32.759);
- polygon.lineTo(-97.06298, 32.755);
-
- {
- JsonParser polygonPathsWgs84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, polygon));
- MapGeometry mPolygonWGS84MP = GeometryEngine
- .jsonToGeometry(polygonPathsWgs84Parser);
-
- assertTrue(polygon.getPointCount() + 1 == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPointCount());
- assertTrue(polygon.getPoint(0).getX() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(0).getX());
- assertTrue(polygon.getPoint(0).getY() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(0).getY());
-
- assertTrue(polygon.getPathCount() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPathCount());
- assertTrue(polygon.getSegmentCount() + 1 == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getSegmentCount());
- assertTrue(polygon.getSegmentCount(0) == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getSegmentCount(0));
- assertTrue(polygon.getSegmentCount(1) + 1 == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getSegmentCount(1));
-
- int lastIndex = polygon.getPointCount() - 1;
- assertTrue(polygon.getPoint(lastIndex).getX() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(lastIndex).getX());
- assertTrue(polygon.getPoint(lastIndex).getY() == ((Polygon) mPolygonWGS84MP
- .getGeometry()).getPoint(lastIndex).getY());
-
- assertTrue(spatialReferenceWGS84.getID() == mPolygonWGS84MP
- .getSpatialReference().getID());
-
- Polygon emptyPolygon = new Polygon();
- String emptyPolygonString = GeometryEngine.geometryToJson(
- spatialReferenceWGS84, emptyPolygon);
- polygonPathsWgs84Parser = factory
- .createJsonParser(emptyPolygonString);
- mPolygonWGS84MP = GeometryEngine
- .jsonToGeometry(polygonPathsWgs84Parser);
-
- assertTrue(mPolygonWGS84MP.getGeometry().isEmpty());
- assertTrue(spatialReferenceWGS84.getID() == mPolygonWGS84MP
- .getSpatialReference().getID());
- }
- }
-
- @Test
- public void testEnvelope() throws JsonParseException, IOException {
- Envelope envelope = new Envelope();
- envelope.setCoords(-109.55, 25.76, -86.39, 49.94);
-
- {
- JsonParser envelopeWGS84Parser = factory
- .createJsonParser(GeometryEngine.geometryToJson(
- spatialReferenceWGS84, envelope));
- MapGeometry envelopeWGS84MP = GeometryEngine
- .jsonToGeometry(envelopeWGS84Parser);
- assertTrue(envelope.isEmpty() == envelopeWGS84MP.getGeometry()
- .isEmpty());
- assertTrue(envelope.getXMax() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getXMax());
- assertTrue(envelope.getYMax() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getYMax());
- assertTrue(envelope.getXMin() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getXMin());
- assertTrue(envelope.getYMin() == ((Envelope) envelopeWGS84MP
- .getGeometry()).getYMin());
- assertTrue(spatialReferenceWGS84.getID() == envelopeWGS84MP
- .getSpatialReference().getID());
-
- Envelope emptyEnvelope = new Envelope();
- String emptyEnvString = GeometryEngine.geometryToJson(
- spatialReferenceWGS84, emptyEnvelope);
- envelopeWGS84Parser = factory.createJsonParser(emptyEnvString);
- envelopeWGS84MP = GeometryEngine
- .jsonToGeometry(envelopeWGS84Parser);
-
- assertTrue(envelopeWGS84MP.getGeometry().isEmpty());
- assertTrue(spatialReferenceWGS84.getID() == envelopeWGS84MP
- .getSpatialReference().getID());
- }
- }
-
- @Test
- public void testCR181369() throws JsonParseException, IOException {
- // CR181369
- {
- String jsonStringPointAndWKT = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkt\" : \"PROJCS[\\\"NAD83_UTM_zone_15N\\\",GEOGCS[\\\"GCS_North_American_1983\\\",DATUM[\\\"D_North_American_1983\\\",SPHEROID[\\\"GRS_1980\\\",6378137.0,298.257222101]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Transverse_Mercator\\\"],PARAMETER[\\\"false_easting\\\",500000.0],PARAMETER[\\\"false_northing\\\",0.0],PARAMETER[\\\"central_meridian\\\",-93.0],PARAMETER[\\\"scale_factor\\\",0.9996],PARAMETER[\\\"latitude_of_origin\\\",0.0],UNIT[\\\"Meter\\\",1.0]]\"} }";
- JsonParser jsonParserPointAndWKT = factory
- .createJsonParser(jsonStringPointAndWKT);
- MapGeometry mapGeom2 = GeometryEngine
- .jsonToGeometry(jsonParserPointAndWKT);
- String jsonStringPointAndWKT2 = GeometryEngine.geometryToJson(
- mapGeom2.getSpatialReference(), mapGeom2.getGeometry());
- JsonParser jsonParserPointAndWKT2 = factory
- .createJsonParser(jsonStringPointAndWKT2);
- MapGeometry mapGeom3 = GeometryEngine
- .jsonToGeometry(jsonParserPointAndWKT2);
- assertTrue(((Point) mapGeom2.getGeometry()).getX() == ((Point) mapGeom3
- .getGeometry()).getX());
- assertTrue(((Point) mapGeom2.getGeometry()).getY() == ((Point) mapGeom3
- .getGeometry()).getY());
- assertTrue(mapGeom2.getSpatialReference().getText()
- .equals(mapGeom3.getSpatialReference().getText()));
- assertTrue(mapGeom2.getSpatialReference().getID() == mapGeom3
- .getSpatialReference().getID());
- }
- }
-
- @Test
- public void testSpatialRef() throws JsonParseException, IOException {
- // String jsonStringPt =
- // "{\"x\":-20037508.342787,\"y\":20037508.342787},\"spatialReference\":{\"wkid\":102100}}";
- String jsonStringPt = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkid\": 102100}}";// 102100
- @SuppressWarnings("unused")
- String jsonStringPt2 = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkid\":4326}}";
- String jsonStringMpt = "{ \"points\" : [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], \"spatialReference\" : {\"wkid\" : 4326}}";// 4326
- String jsonStringMpt3D = "{\"hasZs\" : true,\"points\" : [ [-97.06138,32.837,35.0], [-97.06133,32.836,35.1], [-97.06124,32.834,35.2], [-97.06127,32.832,35.3] ],\"spatialReference\" : {\"wkid\" : 4326}}";
- String jsonStringPl = "{\"paths\" : [ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], [ [-97.06326,32.759], [-97.06298,32.755] ]],\"spatialReference\" : {\"wkid\" : 4326}}";
- String jsonStringPl3D = "{\"hasMs\" : true,\"paths\" : [[ [-97.06138,32.837,5], [-97.06133,32.836,6], [-97.06124,32.834,7], [-97.06127,32.832,8] ],[ [-97.06326,32.759], [-97.06298,32.755] ]],\"spatialReference\" : {\"wkid\" : 4326}}";
- String jsonStringPg = "{ \"rings\" :[ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832], [-97.06138,32.837] ], [ [-97.06326,32.759], [-97.06298,32.755], [-97.06153,32.749], [-97.06326,32.759] ]], \"spatialReference\" : {\"wkt\" : \"\"}}";
- String jsonStringPg3D = "{\"hasZs\" : true,\"hasMs\" : true,\"rings\" : [ [ [-97.06138, 32.837, 35.1, 4], [-97.06133, 32.836, 35.2, 4.1], [-97.06124, 32.834, 35.3, 4.2], [-97.06127, 32.832, 35.2, 44.3], [-97.06138, 32.837, 35.1, 4] ],[ [-97.06326, 32.759, 35.4], [-97.06298, 32.755, 35.5], [-97.06153, 32.749, 35.6], [-97.06326, 32.759, 35.4] ]],\"spatialReference\" : {\"wkid\" : 4326}}";
- String jsonStringPg2 = "{ \"spatialReference\" : {\"wkid\" : 4326}, \"rings\" : [[[-118.35,32.81],[-118.42,32.806],[-118.511,32.892],[-118.35,32.81]]]}";
- String jsonStringPg3 = "{ \"spatialReference\": {\"layerName\":\"GAS_POINTS\",\"name\":null,\"sdesrid\":102100,\"wkid\":102100,\"wkt\":null}}";
- String jsonString2SpatialReferences = "{ \"spatialReference\": {\"layerName\":\"GAS_POINTS\",\"name\":null,\"sdesrid\":102100,\"wkid\":102100,\"wkt\":\"GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137,298.257223563]],PRIMEM[\\\"Greenwich\\\",0],UNIT[\\\"Degree\\\",0.017453292519943295]]\"}}";
- String jsonString2SpatialReferences2 = "{ \"spatialReference\": {\"layerName\":\"GAS_POINTS\",\"name\":null,\"sdesrid\":10,\"wkid\":10,\"wkt\":\"GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137,298.257223563]],PRIMEM[\\\"Greenwich\\\",0],UNIT[\\\"Degree\\\",0.017453292519943295]]\"}}";
- String jsonStringSR = "{\"wkid\" : 4326}";
- String jsonStringEnv = "{\"xmin\" : -109.55, \"ymin\" : 25.76, \"xmax\" : -86.39, \"ymax\" : 49.94,\"spatialReference\" : {\"wkid\" : 4326}}";
- String jsonStringHongKon = "{\"xmin\" : -122.55, \"ymin\" : 37.65, \"xmax\" : -122.28, \"ymax\" : 37.84,\"spatialReference\" : {\"wkid\" : 4326}}";
- @SuppressWarnings("unused")
- String jsonStringWKT = " {\"wkt\" : \"GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137,298.257223563]],PRIMEM[\\\"Greenwich\\\",0],UNIT[\\\"Degree\\\",0.017453292519943295]]\"}";
- String jsonStringInvalidWKID = "{\"x\":10.0,\"y\":20.0},\"spatialReference\":{\"wkid\":35253523}}";
- String jsonStringOregon = "{\"xmin\":7531831.219849482,\"ymin\":585702.9799639136,\"xmax\":7750143.589982405,\"ymax\":733289.6299999952,\"spatialReference\":{\"wkid\":102726}}";
-
- JsonParser jsonParserPt = factory.createJsonParser(jsonStringPt);
- JsonParser jsonParserMpt = factory.createJsonParser(jsonStringMpt);
- JsonParser jsonParserMpt3D = factory.createJsonParser(jsonStringMpt3D);
- JsonParser jsonParserPl = factory.createJsonParser(jsonStringPl);
- JsonParser jsonParserPl3D = factory.createJsonParser(jsonStringPl3D);
- JsonParser jsonParserPg = factory.createJsonParser(jsonStringPg);
- JsonParser jsonParserPg3D = factory.createJsonParser(jsonStringPg3D);
- JsonParser jsonParserPg2 = factory.createJsonParser(jsonStringPg2);
- @SuppressWarnings("unused")
- JsonParser jsonParserSR = factory.createJsonParser(jsonStringSR);
- JsonParser jsonParserEnv = factory.createJsonParser(jsonStringEnv);
- JsonParser jsonParserPg3 = factory.createJsonParser(jsonStringPg3);
- @SuppressWarnings("unused")
- JsonParser jsonParserCrazy1 = factory
- .createJsonParser(jsonString2SpatialReferences);
- @SuppressWarnings("unused")
- JsonParser jsonParserCrazy2 = factory
- .createJsonParser(jsonString2SpatialReferences2);
- JsonParser jsonParserInvalidWKID = factory
- .createJsonParser(jsonStringInvalidWKID);
- @SuppressWarnings("unused")
- JsonParser jsonParseHongKon = factory
- .createJsonParser(jsonStringHongKon);
- JsonParser jsonParseOregon = factory.createJsonParser(jsonStringOregon);
-
- MapGeometry mapGeom = GeometryEngine.jsonToGeometry(jsonParserPt);
- // showProjectedGeometryInfo(mapGeom);
- Assert.assertTrue(mapGeom.getSpatialReference().getID() == 102100);
-
- MapGeometry mapGeomOregon = GeometryEngine
- .jsonToGeometry(jsonParseOregon);
- Assert.assertTrue(mapGeomOregon.getSpatialReference().getID() == 102726);
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserMpt);
- Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserMpt3D);
- Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
- {
- Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(0)
- .getX() == -97.06138);
- Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(0)
- .getY() == 32.837);
- Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(3)
- .getX() == -97.06127);
- Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(3)
- .getY() == 32.832);
- }
- // showProjectedGeometryInfo(mapGeom);
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserPl);
- Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
- // showProjectedGeometryInfo(mapGeom);
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserPl3D);
- {
- // [[ [-97.06138,32.837,5], [-97.06133,32.836,6],
- // [-97.06124,32.834,7], [-97.06127,32.832,8] ],
- // [ [-97.06326,32.759], [-97.06298,32.755] ]]";
- Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(0)
- .getX() == -97.06138);
- Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(0)
- .getY() == 32.837);
- int lastIndex = ((Polyline) mapGeom.getGeometry()).getPointCount() - 1;
- Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(
- lastIndex).getX() == -97.06298);// -97.06153, 32.749
- Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(
- lastIndex).getY() == 32.755);
- int lastIndexFirstLine = ((Polyline) mapGeom.getGeometry())
- .getPathEnd(0) - 1;
- Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(
- lastIndexFirstLine).getX() == -97.06127);// -97.06153,
- // 32.749
- Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(
- lastIndexFirstLine).getY() == 32.832);
- }
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg);
- Assert.assertTrue(mapGeom.getSpatialReference() == null);
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg3D);
- {
- Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(0)
- .getX() == -97.06138);
- Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(0)
- .getY() == 32.837);
- int lastIndex = ((Polygon) mapGeom.getGeometry()).getPointCount() - 1;
- Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(
- lastIndex).getX() == -97.06153);// -97.06153, 32.749
- Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(
- lastIndex).getY() == 32.749);
- }
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg2);
- Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
- // showProjectedGeometryInfo(mapGeom);
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg3);
- Assert.assertTrue(mapGeom.getSpatialReference().getID() == 102100);
- // showProjectedGeometryInfo(mapGeom);
-
- // mapGeom = GeometryEngine.jsonToGeometry(jsonParserCrazy1);
- // Assert.assertTrue(mapGeom.getSpatialReference().getText().equals(""));
- // showProjectedGeometryInfo(mapGeom);
-
- mapGeom = GeometryEngine.jsonToGeometry(jsonParserEnv);
- Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
- // showProjectedGeometryInfo(mapGeom);
- // System.out.println("\n\nWKID: "+
- // SpatialReference.create(wkid).fromJson(jsonParserSR).getID());
-
- try {
- GeometryEngine.jsonToGeometry(jsonParserInvalidWKID);
- } catch (Exception ex) {
- System.out.print(ex.getMessage());
- }
- }
-
- @Test
- public void testMP2onCR175871() throws Exception {
- Polygon pg = new Polygon();
- pg.startPath(-50, 10);
- pg.lineTo(-50, 12);
- pg.lineTo(-45, 12);
- pg.lineTo(-45, 10);
-
- Polygon pg1 = new Polygon();
- pg1.startPath(-45, 10);
- pg1.lineTo(-40, 10);
- pg1.lineTo(-40, 8);
- pg.add(pg1, false);
-
- SpatialReference spatialReference = SpatialReference.create(4326);
-
- try {
- String jSonStr = GeometryEngine
- .geometryToJson(spatialReference, pg);
- JsonFactory jf = new JsonFactory();
-
- JsonParser jp = jf.createJsonParser(jSonStr);
- jp.nextToken();
- MapGeometry mg = GeometryEngine.jsonToGeometry(jp);
- Geometry gm = mg.getGeometry();
- Assert.assertEquals(Geometry.Type.Polygon, gm.getType());
- Assert.assertTrue(mg.getSpatialReference().getID() == 4326);
-
- Polygon pgNew = (Polygon) gm;
-
- Assert.assertEquals(pgNew.getPathCount(), pg.getPathCount());
- Assert.assertEquals(pgNew.getPointCount(), pg.getPointCount());
- Assert.assertEquals(pgNew.getSegmentCount(), pg.getSegmentCount());
-
- Assert.assertEquals(pgNew.getPoint(0).getX(),
- pg.getPoint(0).getX(), 0.000000001);
- Assert.assertEquals(pgNew.getPoint(1).getX(),
- pg.getPoint(1).getX(), 0.000000001);
- Assert.assertEquals(pgNew.getPoint(2).getX(),
- pg.getPoint(2).getX(), 0.000000001);
- Assert.assertEquals(pgNew.getPoint(3).getX(),
- pg.getPoint(3).getX(), 0.000000001);
-
- Assert.assertEquals(pgNew.getPoint(0).getY(),
- pg.getPoint(0).getY(), 0.000000001);
- Assert.assertEquals(pgNew.getPoint(1).getY(),
- pg.getPoint(1).getY(), 0.000000001);
- Assert.assertEquals(pgNew.getPoint(2).getY(),
- pg.getPoint(2).getY(), 0.000000001);
- Assert.assertEquals(pgNew.getPoint(3).getY(),
- pg.getPoint(3).getY(), 0.000000001);
- } catch (Exception ex) {
- String err = ex.getMessage();
- System.out.print(err);
- throw ex;
- }
- }
-
- @Test
- public static int fromJsonToWkid(JsonParser parser)
- throws JsonParseException, IOException {
- int wkid = 0;
- if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
- return 0;
- }
-
- while (parser.nextToken() != JsonToken.END_OBJECT) {
- String fieldName = parser.getCurrentName();
-
- if ("wkid".equals(fieldName)) {
- parser.nextToken();
- wkid = parser.getIntValue();
- }
- }
- return wkid;
- }
-
- @SuppressWarnings("unused")
- private static void showProjectedGeometryInfo(MapGeometry mapGeom) {
- System.out.println("\n");
- MapGeometry geom = mapGeom;
- // while ((geom = geomCursor.next()) != null) {
-
- if (geom.getGeometry() instanceof Point) {
- Point pnt = (Point) geom.getGeometry();
- System.out
- .println("Point(" + pnt.getX() + " , " + pnt.getY() + ")");
- if (geom.getSpatialReference() == null)
- System.out.println("No spatial reference");
- else
- System.out.println("wkid: "
- + geom.getSpatialReference().getID());
-
- } else if (geom.getGeometry() instanceof MultiPoint) {
- MultiPoint mp = (MultiPoint) geom.getGeometry();
- System.out.println("Multipoint has " + mp.getPointCount()
- + " points.");
-
- System.out.println("wkid: " + geom.getSpatialReference().getID());
-
- } else if (geom.getGeometry() instanceof Polygon) {
- Polygon mp = (Polygon) geom.getGeometry();
- System.out.println("Polygon has " + mp.getPointCount()
- + " points and " + mp.getPathCount() + " parts.");
- if (mp.getPathCount() > 1) {
- System.out.println("Part start of 2nd segment : "
- + mp.getPathStart(1));
- System.out.println("Part end of 2nd segment : "
- + mp.getPathEnd(1));
- System.out.println("Part size of 2nd segment : "
- + mp.getPathSize(1));
-
- int start = mp.getPathStart(1);
- int end = mp.getPathEnd(1);
- for (int i = start; i < end; i++) {
- Point pp = mp.getPoint(i);
- System.out.println("Point(" + i + ") = (" + pp.getX()
- + ", " + pp.getY() + ")");
- }
- }
- System.out.println("wkid: " + geom.getSpatialReference().getID());
-
- } else if (geom.getGeometry() instanceof Polyline) {
- Polyline mp = (Polyline) geom.getGeometry();
- System.out.println("Polyline has " + mp.getPointCount()
- + " points and " + mp.getPathCount() + " parts.");
- System.out.println("Part start of 2nd segment : "
- + mp.getPathStart(1));
- System.out.println("Part end of 2nd segment : "
- + mp.getPathEnd(1));
- System.out.println("Part size of 2nd segment : "
- + mp.getPathSize(1));
- int start = mp.getPathStart(1);
- int end = mp.getPathEnd(1);
- for (int i = start; i < end; i++) {
- Point pp = mp.getPoint(i);
- System.out.println("Point(" + i + ") = (" + pp.getX() + ", "
- + pp.getY() + ")");
- }
-
- System.out.println("wkid: " + geom.getSpatialReference().getID());
- }
- }
-
- @Test
- public void testGeometryToJSON() {
- Polygon geom = new Polygon();
- geom.startPath(new Point(-113, 34));
- geom.lineTo(new Point(-105, 34));
- geom.lineTo(new Point(-108, 40));
-
- String outputPolygon1 = GeometryEngine.geometryToJson(-1, geom);// Test
- // WKID
- // == -1
- System.out.println("Geom JSON STRING is" + outputPolygon1);
- String correctPolygon1 = "{\"rings\":[[[-113.0,34.0],[-105.0,34.0],[-108.0,40.0],[-113.0,34.0]]]}";
-
- assertEquals(correctPolygon1, outputPolygon1);
-
- String outputPolygon2 = GeometryEngine.geometryToJson(4326, geom);
- System.out.println("Geom JSON STRING is" + outputPolygon2);
-
- String correctPolygon2 = "{\"rings\":[[[-113.0,34.0],[-105.0,34.0],[-108.0,40.0],[-113.0,34.0]]],\"spatialReference\":{\"wkid\":4326}}";
- assertEquals(correctPolygon2, outputPolygon2);
- }
-
- @Test
- public void testGeometryToJSONOldID() throws Exception {// CR
- Polygon geom = new Polygon();
- geom.startPath(new Point(-113, 34));
- geom.lineTo(new Point(-105, 34));
- geom.lineTo(new Point(-108, 40));
- String outputPolygon = GeometryEngine.geometryToJson(
- SpatialReference.create(3857), geom);// Test WKID == -1
- String correctPolygon = "{\"rings\":[[[-113.0,34.0],[-105.0,34.0],[-108.0,40.0],[-113.0,34.0]]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}";
- assertTrue(outputPolygon.equals(correctPolygon));
- JsonFactory jf = new JsonFactory();
- JsonParser jp = jf.createJsonParser(outputPolygon);
- jp.nextToken();
- MapGeometry mg = GeometryEngine.jsonToGeometry(jp);
- @SuppressWarnings("unused")
- int srId = mg.getSpatialReference().getID();
- @SuppressWarnings("unused")
- int srOldId = mg.getSpatialReference().getOldID();
- Assert.assertTrue(mg.getSpatialReference().getID() == 3857);
- Assert.assertTrue(mg.getSpatialReference().getLatestID() == 3857);
- Assert.assertTrue(mg.getSpatialReference().getOldID() == 102100);
- }
-}
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.util.Hashtable;
+import java.io.IOException;
+import java.util.Map;
+import junit.framework.TestCase;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+
+public class TestJsonParser extends TestCase {
+
+ JsonFactory factory = new JsonFactory();
+ SpatialReference spatialReferenceWebMerc1 = SpatialReference.create(102100);
+ SpatialReference spatialReferenceWebMerc2 = SpatialReference.create(spatialReferenceWebMerc1.getLatestID());
+ SpatialReference spatialReferenceWGS84 = SpatialReference.create(4326);
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void test3DPoint() throws JsonParseException, IOException {
+ String jsonString3DPt = "{\"x\" : -118.15, \"y\" : 33.80, \"z\" : 10.0, \"spatialReference\" : {\"wkid\" : 4326}}";
+
+ JsonParser jsonParser3DPt = factory.createParser(jsonString3DPt);
+ MapGeometry point3DMP = GeometryEngine.jsonToGeometry(jsonParser3DPt);
+ assertTrue(-118.15 == ((Point) point3DMP.getGeometry()).getX());
+ assertTrue(33.80 == ((Point) point3DMP.getGeometry()).getY());
+ assertTrue(spatialReferenceWGS84.getID() == point3DMP.getSpatialReference().getID());
+ }
+
+ @Test
+ public void test3DPoint1() throws JsonParseException, IOException {
+ Point point1 = new Point(10.0, 20.0);
+ Point pointEmpty = new Point();
+ {
+ JsonParser pointWebMerc1Parser = factory
+ .createJsonParser(GeometryEngine.geometryToJson(spatialReferenceWebMerc1, point1));
+ MapGeometry pointWebMerc1MP = GeometryEngine.jsonToGeometry(pointWebMerc1Parser);
+ assertTrue(point1.getX() == ((Point) pointWebMerc1MP.getGeometry()).getX());
+ assertTrue(point1.getY() == ((Point) pointWebMerc1MP.getGeometry()).getY());
+ int srIdOri = spatialReferenceWebMerc1.getID();
+ int srIdAfter = pointWebMerc1MP.getSpatialReference().getID();
+ assertTrue(srIdOri == srIdAfter || srIdAfter == 3857);
+
+ pointWebMerc1Parser = factory.createJsonParser(GeometryEngine.geometryToJson(null, point1));
+ pointWebMerc1MP = GeometryEngine.jsonToGeometry(pointWebMerc1Parser);
+ assertTrue(null == pointWebMerc1MP.getSpatialReference());
+
+ String pointEmptyString = GeometryEngine.geometryToJson(spatialReferenceWebMerc1, pointEmpty);
+ pointWebMerc1Parser = factory.createJsonParser(pointEmptyString);
+
+ pointWebMerc1MP = GeometryEngine.jsonToGeometry(pointWebMerc1Parser);
+ assertTrue(pointWebMerc1MP.getGeometry().isEmpty());
+ int srIdOri2 = spatialReferenceWebMerc1.getID();
+ int srIdAfter2 = pointWebMerc1MP.getSpatialReference().getID();
+ assertTrue(srIdOri2 == srIdAfter2 || srIdAfter2 == 3857);
+ }
+ }
+
+ @Test
+ public void test3DPoint2() throws JsonParseException, IOException {
+ {
+ Point point1 = new Point(10.0, 20.0);
+ JsonParser pointWebMerc2Parser = factory
+ .createJsonParser(GeometryEngine.geometryToJson(spatialReferenceWebMerc2, point1));
+ MapGeometry pointWebMerc2MP = GeometryEngine.jsonToGeometry(pointWebMerc2Parser);
+ assertTrue(point1.getX() == ((Point) pointWebMerc2MP.getGeometry()).getX());
+ assertTrue(point1.getY() == ((Point) pointWebMerc2MP.getGeometry()).getY());
+ assertTrue(spatialReferenceWebMerc2.getLatestID() == pointWebMerc2MP.getSpatialReference().getLatestID());
+ }
+ }
+
+ @Test
+ public void test3DPoint3() throws JsonParseException, IOException {
+ {
+ Point point1 = new Point(10.0, 20.0);
+ JsonParser pointWgs84Parser = factory
+ .createJsonParser(GeometryEngine.geometryToJson(spatialReferenceWGS84, point1));
+ MapGeometry pointWgs84MP = GeometryEngine.jsonToGeometry(pointWgs84Parser);
+ assertTrue(point1.getX() == ((Point) pointWgs84MP.getGeometry()).getX());
+ assertTrue(point1.getY() == ((Point) pointWgs84MP.getGeometry()).getY());
+ assertTrue(spatialReferenceWGS84.getID() == pointWgs84MP.getSpatialReference().getID());
+ }
+ }
+
+ @Test
+ public void testMultiPoint() throws JsonParseException, IOException {
+ MultiPoint multiPoint1 = new MultiPoint();
+ multiPoint1.add(-97.06138, 32.837);
+ multiPoint1.add(-97.06133, 32.836);
+ multiPoint1.add(-97.06124, 32.834);
+ multiPoint1.add(-97.06127, 32.832);
+
+ {
+ JsonParser mPointWgs84Parser = factory
+ .createJsonParser(GeometryEngine.geometryToJson(spatialReferenceWGS84, multiPoint1));
+ MapGeometry mPointWgs84MP = GeometryEngine.jsonToGeometry(mPointWgs84Parser);
+ assertTrue(multiPoint1.getPointCount() == ((MultiPoint) mPointWgs84MP.getGeometry()).getPointCount());
+ assertTrue(multiPoint1.getPoint(0).getX() == ((MultiPoint) mPointWgs84MP.getGeometry()).getPoint(0).getX());
+ assertTrue(multiPoint1.getPoint(0).getY() == ((MultiPoint) mPointWgs84MP.getGeometry()).getPoint(0).getY());
+ int lastIndex = multiPoint1.getPointCount() - 1;
+ assertTrue(multiPoint1.getPoint(lastIndex).getX() == ((MultiPoint) mPointWgs84MP.getGeometry())
+ .getPoint(lastIndex).getX());
+ assertTrue(multiPoint1.getPoint(lastIndex).getY() == ((MultiPoint) mPointWgs84MP.getGeometry())
+ .getPoint(lastIndex).getY());
+
+ assertTrue(spatialReferenceWGS84.getID() == mPointWgs84MP.getSpatialReference().getID());
+
+ MultiPoint mPointEmpty = new MultiPoint();
+ String mPointEmptyString = GeometryEngine.geometryToJson(spatialReferenceWGS84, mPointEmpty);
+ mPointWgs84Parser = factory.createJsonParser(mPointEmptyString);
+
+ mPointWgs84MP = GeometryEngine.jsonToGeometry(mPointWgs84Parser);
+ assertTrue(mPointWgs84MP.getGeometry().isEmpty());
+ assertTrue(spatialReferenceWGS84.getID() == mPointWgs84MP.getSpatialReference().getID());
+
+ }
+ }
+
+ @Test
+ public void testPolyline() throws JsonParseException, IOException {
+ Polyline polyline = new Polyline();
+ polyline.startPath(-97.06138, 32.837);
+ polyline.lineTo(-97.06133, 32.836);
+ polyline.lineTo(-97.06124, 32.834);
+ polyline.lineTo(-97.06127, 32.832);
+
+ polyline.startPath(-97.06326, 32.759);
+ polyline.lineTo(-97.06298, 32.755);
+
+ {
+ JsonParser polylinePathsWgs84Parser = factory
+ .createJsonParser(GeometryEngine.geometryToJson(spatialReferenceWGS84, polyline));
+ MapGeometry mPolylineWGS84MP = GeometryEngine.jsonToGeometry(polylinePathsWgs84Parser);
+
+ assertTrue(polyline.getPointCount() == ((Polyline) mPolylineWGS84MP.getGeometry()).getPointCount());
+ assertTrue(polyline.getPoint(0).getX() == ((Polyline) mPolylineWGS84MP.getGeometry()).getPoint(0).getX());
+ assertTrue(polyline.getPoint(0).getY() == ((Polyline) mPolylineWGS84MP.getGeometry()).getPoint(0).getY());
+
+ assertTrue(polyline.getPathCount() == ((Polyline) mPolylineWGS84MP.getGeometry()).getPathCount());
+ assertTrue(polyline.getSegmentCount() == ((Polyline) mPolylineWGS84MP.getGeometry()).getSegmentCount());
+ assertTrue(polyline.getSegmentCount(0) == ((Polyline) mPolylineWGS84MP.getGeometry()).getSegmentCount(0));
+ assertTrue(polyline.getSegmentCount(1) == ((Polyline) mPolylineWGS84MP.getGeometry()).getSegmentCount(1));
+
+ int lastIndex = polyline.getPointCount() - 1;
+ assertTrue(polyline.getPoint(lastIndex).getX() == ((Polyline) mPolylineWGS84MP.getGeometry())
+ .getPoint(lastIndex).getX());
+ assertTrue(polyline.getPoint(lastIndex).getY() == ((Polyline) mPolylineWGS84MP.getGeometry())
+ .getPoint(lastIndex).getY());
+
+ assertTrue(spatialReferenceWGS84.getID() == mPolylineWGS84MP.getSpatialReference().getID());
+
+ Polyline emptyPolyline = new Polyline();
+ String emptyString = GeometryEngine.geometryToJson(spatialReferenceWGS84, emptyPolyline);
+ mPolylineWGS84MP = GeometryEngine.jsonToGeometry(factory.createJsonParser(emptyString));
+ assertTrue(mPolylineWGS84MP.getGeometry().isEmpty());
+ assertTrue(spatialReferenceWGS84.getID() == mPolylineWGS84MP.getSpatialReference().getID());
+ }
+ }
+
+ @Test
+ public void testPolygon() throws JsonParseException, IOException {
+ Polygon polygon = new Polygon();
+ polygon.startPath(-97.06138, 32.837);
+ polygon.lineTo(-97.06133, 32.836);
+ polygon.lineTo(-97.06124, 32.834);
+ polygon.lineTo(-97.06127, 32.832);
+
+ polygon.startPath(-97.06326, 32.759);
+ polygon.lineTo(-97.06298, 32.755);
+
+ {
+ JsonParser polygonPathsWgs84Parser = factory
+ .createJsonParser(GeometryEngine.geometryToJson(spatialReferenceWGS84, polygon));
+ MapGeometry mPolygonWGS84MP = GeometryEngine.jsonToGeometry(polygonPathsWgs84Parser);
+
+ assertTrue(polygon.getPointCount() + 1 == ((Polygon) mPolygonWGS84MP.getGeometry()).getPointCount());
+ assertTrue(polygon.getPoint(0).getX() == ((Polygon) mPolygonWGS84MP.getGeometry()).getPoint(0).getX());
+ assertTrue(polygon.getPoint(0).getY() == ((Polygon) mPolygonWGS84MP.getGeometry()).getPoint(0).getY());
+
+ assertTrue(polygon.getPathCount() == ((Polygon) mPolygonWGS84MP.getGeometry()).getPathCount());
+ assertTrue(polygon.getSegmentCount() + 1 == ((Polygon) mPolygonWGS84MP.getGeometry()).getSegmentCount());
+ assertTrue(polygon.getSegmentCount(0) == ((Polygon) mPolygonWGS84MP.getGeometry()).getSegmentCount(0));
+ assertTrue(polygon.getSegmentCount(1) + 1 == ((Polygon) mPolygonWGS84MP.getGeometry()).getSegmentCount(1));
+
+ int lastIndex = polygon.getPointCount() - 1;
+ assertTrue(polygon.getPoint(lastIndex).getX() == ((Polygon) mPolygonWGS84MP.getGeometry())
+ .getPoint(lastIndex).getX());
+ assertTrue(polygon.getPoint(lastIndex).getY() == ((Polygon) mPolygonWGS84MP.getGeometry())
+ .getPoint(lastIndex).getY());
+
+ assertTrue(spatialReferenceWGS84.getID() == mPolygonWGS84MP.getSpatialReference().getID());
+
+ Polygon emptyPolygon = new Polygon();
+ String emptyPolygonString = GeometryEngine.geometryToJson(spatialReferenceWGS84, emptyPolygon);
+ polygonPathsWgs84Parser = factory.createJsonParser(emptyPolygonString);
+ mPolygonWGS84MP = GeometryEngine.jsonToGeometry(polygonPathsWgs84Parser);
+
+ assertTrue(mPolygonWGS84MP.getGeometry().isEmpty());
+ assertTrue(spatialReferenceWGS84.getID() == mPolygonWGS84MP.getSpatialReference().getID());
+ }
+ }
+
+ @Test
+ public void testEnvelope() throws JsonParseException, IOException {
+ Envelope envelope = new Envelope();
+ envelope.setCoords(-109.55, 25.76, -86.39, 49.94);
+
+ {
+ JsonParser envelopeWGS84Parser = factory
+ .createJsonParser(GeometryEngine.geometryToJson(spatialReferenceWGS84, envelope));
+ MapGeometry envelopeWGS84MP = GeometryEngine.jsonToGeometry(envelopeWGS84Parser);
+ assertTrue(envelope.isEmpty() == envelopeWGS84MP.getGeometry().isEmpty());
+ assertTrue(envelope.getXMax() == ((Envelope) envelopeWGS84MP.getGeometry()).getXMax());
+ assertTrue(envelope.getYMax() == ((Envelope) envelopeWGS84MP.getGeometry()).getYMax());
+ assertTrue(envelope.getXMin() == ((Envelope) envelopeWGS84MP.getGeometry()).getXMin());
+ assertTrue(envelope.getYMin() == ((Envelope) envelopeWGS84MP.getGeometry()).getYMin());
+ assertTrue(spatialReferenceWGS84.getID() == envelopeWGS84MP.getSpatialReference().getID());
+
+ Envelope emptyEnvelope = new Envelope();
+ String emptyEnvString = GeometryEngine.geometryToJson(spatialReferenceWGS84, emptyEnvelope);
+ envelopeWGS84Parser = factory.createJsonParser(emptyEnvString);
+ envelopeWGS84MP = GeometryEngine.jsonToGeometry(envelopeWGS84Parser);
+
+ assertTrue(envelopeWGS84MP.getGeometry().isEmpty());
+ assertTrue(spatialReferenceWGS84.getID() == envelopeWGS84MP.getSpatialReference().getID());
+ }
+ }
+
+ @Test
+ public void testCR181369() throws JsonParseException, IOException {
+ // CR181369
+ {
+ String jsonStringPointAndWKT = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkt\" : \"PROJCS[\\\"NAD83_UTM_zone_15N\\\",GEOGCS[\\\"GCS_North_American_1983\\\",DATUM[\\\"D_North_American_1983\\\",SPHEROID[\\\"GRS_1980\\\",6378137.0,298.257222101]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Transverse_Mercator\\\"],PARAMETER[\\\"false_easting\\\",500000.0],PARAMETER[\\\"false_northing\\\",0.0],PARAMETER[\\\"central_meridian\\\",-93.0],PARAMETER[\\\"scale_factor\\\",0.9996],PARAMETER[\\\"latitude_of_origin\\\",0.0],UNIT[\\\"Meter\\\",1.0]]\"} }";
+ JsonParser jsonParserPointAndWKT = factory.createJsonParser(jsonStringPointAndWKT);
+ MapGeometry mapGeom2 = GeometryEngine.jsonToGeometry(jsonParserPointAndWKT);
+ String jsonStringPointAndWKT2 = GeometryEngine.geometryToJson(mapGeom2.getSpatialReference(),
+ mapGeom2.getGeometry());
+ JsonParser jsonParserPointAndWKT2 = factory.createJsonParser(jsonStringPointAndWKT2);
+ MapGeometry mapGeom3 = GeometryEngine.jsonToGeometry(jsonParserPointAndWKT2);
+ assertTrue(((Point) mapGeom2.getGeometry()).getX() == ((Point) mapGeom3.getGeometry()).getX());
+ assertTrue(((Point) mapGeom2.getGeometry()).getY() == ((Point) mapGeom3.getGeometry()).getY());
+ assertTrue(mapGeom2.getSpatialReference().getText().equals(mapGeom3.getSpatialReference().getText()));
+ assertTrue(mapGeom2.getSpatialReference().getID() == mapGeom3.getSpatialReference().getID());
+ }
+ }
+
+ @Test
+ public void testSpatialRef() throws JsonParseException, IOException {
+ // String jsonStringPt =
+ // "{\"x\":-20037508.342787,\"y\":20037508.342787},\"spatialReference\":{\"wkid\":102100}}";
+ String jsonStringPt = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkid\": 102100}}";// 102100
+ @SuppressWarnings("unused")
+ String jsonStringPt2 = "{\"x\":10.0,\"y\":20.0,\"spatialReference\":{\"wkid\":4326}}";
+ String jsonStringMpt = "{ \"points\" : [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], \"spatialReference\" : {\"wkid\" : 4326}}";// 4326
+ String jsonStringMpt3D = "{\"hasZs\" : true,\"points\" : [ [-97.06138,32.837,35.0], [-97.06133,32.836,35.1], [-97.06124,32.834,35.2], [-97.06127,32.832,35.3] ],\"spatialReference\" : {\"wkid\" : 4326}}";
+ String jsonStringPl = "{\"paths\" : [ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], [ [-97.06326,32.759], [-97.06298,32.755] ]],\"spatialReference\" : {\"wkid\" : 4326}}";
+ String jsonStringPl3D = "{\"hasMs\" : true,\"paths\" : [[ [-97.06138,32.837,5], [-97.06133,32.836,6], [-97.06124,32.834,7], [-97.06127,32.832,8] ],[ [-97.06326,32.759], [-97.06298,32.755] ]],\"spatialReference\" : {\"wkid\" : 4326}}";
+ String jsonStringPg = "{ \"rings\" :[ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832], [-97.06138,32.837] ], [ [-97.06326,32.759], [-97.06298,32.755], [-97.06153,32.749], [-97.06326,32.759] ]], \"spatialReference\" : {\"wkt\" : \"\"}}";
+ String jsonStringPg3D = "{\"hasZs\" : true,\"hasMs\" : true,\"rings\" : [ [ [-97.06138, 32.837, 35.1, 4], [-97.06133, 32.836, 35.2, 4.1], [-97.06124, 32.834, 35.3, 4.2], [-97.06127, 32.832, 35.2, 44.3], [-97.06138, 32.837, 35.1, 4] ],[ [-97.06326, 32.759, 35.4], [-97.06298, 32.755, 35.5], [-97.06153, 32.749, 35.6], [-97.06326, 32.759, 35.4] ]],\"spatialReference\" : {\"wkid\" : 4326}}";
+ String jsonStringPg2 = "{ \"spatialReference\" : {\"wkid\" : 4326}, \"rings\" : [[[-118.35,32.81],[-118.42,32.806],[-118.511,32.892],[-118.35,32.81]]]}";
+ String jsonStringPg3 = "{ \"spatialReference\": {\"layerName\":\"GAS_POINTS\",\"name\":null,\"sdesrid\":102100,\"wkid\":102100,\"wkt\":null}}";
+ String jsonString2SpatialReferences = "{ \"spatialReference\": {\"layerName\":\"GAS_POINTS\",\"name\":null,\"sdesrid\":102100,\"wkid\":102100,\"wkt\":\"GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137,298.257223563]],PRIMEM[\\\"Greenwich\\\",0],UNIT[\\\"Degree\\\",0.017453292519943295]]\"}}";
+ String jsonString2SpatialReferences2 = "{ \"spatialReference\": {\"layerName\":\"GAS_POINTS\",\"name\":null,\"sdesrid\":10,\"wkid\":10,\"wkt\":\"GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137,298.257223563]],PRIMEM[\\\"Greenwich\\\",0],UNIT[\\\"Degree\\\",0.017453292519943295]]\"}}";
+ String jsonStringSR = "{\"wkid\" : 4326}";
+ String jsonStringEnv = "{\"xmin\" : -109.55, \"ymin\" : 25.76, \"xmax\" : -86.39, \"ymax\" : 49.94,\"spatialReference\" : {\"wkid\" : 4326}}";
+ String jsonStringHongKon = "{\"xmin\" : -122.55, \"ymin\" : 37.65, \"xmax\" : -122.28, \"ymax\" : 37.84,\"spatialReference\" : {\"wkid\" : 4326}}";
+ @SuppressWarnings("unused")
+ String jsonStringWKT = " {\"wkt\" : \"GEOGCS[\\\"GCS_WGS_1984\\\",DATUM[\\\"D_WGS_1984\\\",SPHEROID[\\\"WGS_1984\\\",6378137,298.257223563]],PRIMEM[\\\"Greenwich\\\",0],UNIT[\\\"Degree\\\",0.017453292519943295]]\"}";
+ String jsonStringInvalidWKID = "{\"x\":10.0,\"y\":20.0},\"spatialReference\":{\"wkid\":35253523}}";
+ String jsonStringOregon = "{\"xmin\":7531831.219849482,\"ymin\":585702.9799639136,\"xmax\":7750143.589982405,\"ymax\":733289.6299999952,\"spatialReference\":{\"wkid\":102726}}";
+
+ JsonParser jsonParserPt = factory.createJsonParser(jsonStringPt);
+ JsonParser jsonParserMpt = factory.createJsonParser(jsonStringMpt);
+ JsonParser jsonParserMpt3D = factory.createJsonParser(jsonStringMpt3D);
+ JsonParser jsonParserPl = factory.createJsonParser(jsonStringPl);
+ JsonParser jsonParserPl3D = factory.createJsonParser(jsonStringPl3D);
+ JsonParser jsonParserPg = factory.createJsonParser(jsonStringPg);
+ JsonParser jsonParserPg3D = factory.createJsonParser(jsonStringPg3D);
+ JsonParser jsonParserPg2 = factory.createJsonParser(jsonStringPg2);
+ @SuppressWarnings("unused")
+ JsonParser jsonParserSR = factory.createJsonParser(jsonStringSR);
+ JsonParser jsonParserEnv = factory.createJsonParser(jsonStringEnv);
+ JsonParser jsonParserPg3 = factory.createJsonParser(jsonStringPg3);
+ @SuppressWarnings("unused")
+ JsonParser jsonParserCrazy1 = factory.createJsonParser(jsonString2SpatialReferences);
+ @SuppressWarnings("unused")
+ JsonParser jsonParserCrazy2 = factory.createJsonParser(jsonString2SpatialReferences2);
+ JsonParser jsonParserInvalidWKID = factory.createJsonParser(jsonStringInvalidWKID);
+ @SuppressWarnings("unused")
+ JsonParser jsonParseHongKon = factory.createJsonParser(jsonStringHongKon);
+ JsonParser jsonParseOregon = factory.createJsonParser(jsonStringOregon);
+
+ MapGeometry mapGeom = GeometryEngine.jsonToGeometry(jsonParserPt);
+ // showProjectedGeometryInfo(mapGeom);
+ Assert.assertTrue(mapGeom.getSpatialReference().getID() == 102100);
+
+ MapGeometry mapGeomOregon = GeometryEngine.jsonToGeometry(jsonParseOregon);
+ Assert.assertTrue(mapGeomOregon.getSpatialReference().getID() == 102726);
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserMpt);
+ Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserMpt3D);
+ Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
+ {
+ Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(0).getX() == -97.06138);
+ Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(0).getY() == 32.837);
+ Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(3).getX() == -97.06127);
+ Assert.assertTrue(((MultiPoint) mapGeom.getGeometry()).getPoint(3).getY() == 32.832);
+ }
+ // showProjectedGeometryInfo(mapGeom);
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserPl);
+ Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
+ // showProjectedGeometryInfo(mapGeom);
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserPl3D);
+ {
+ // [[ [-97.06138,32.837,5], [-97.06133,32.836,6],
+ // [-97.06124,32.834,7], [-97.06127,32.832,8] ],
+ // [ [-97.06326,32.759], [-97.06298,32.755] ]]";
+ Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(0).getX() == -97.06138);
+ Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(0).getY() == 32.837);
+ int lastIndex = ((Polyline) mapGeom.getGeometry()).getPointCount() - 1;
+ Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(lastIndex).getX() == -97.06298);// -97.06153,
+ // 32.749
+ Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(lastIndex).getY() == 32.755);
+ int lastIndexFirstLine = ((Polyline) mapGeom.getGeometry()).getPathEnd(0) - 1;
+ Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(lastIndexFirstLine).getX() == -97.06127);// -97.06153,
+ // 32.749
+ Assert.assertTrue(((Polyline) mapGeom.getGeometry()).getPoint(lastIndexFirstLine).getY() == 32.832);
+ }
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg);
+ Assert.assertTrue(mapGeom.getSpatialReference() == null);
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg3D);
+ {
+ Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(0).getX() == -97.06138);
+ Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(0).getY() == 32.837);
+ int lastIndex = ((Polygon) mapGeom.getGeometry()).getPointCount() - 1;
+ Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(lastIndex).getX() == -97.06153);// -97.06153,
+ // 32.749
+ Assert.assertTrue(((Polygon) mapGeom.getGeometry()).getPoint(lastIndex).getY() == 32.749);
+ }
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg2);
+ Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
+ // showProjectedGeometryInfo(mapGeom);
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserPg3);
+ Assert.assertTrue(mapGeom.getSpatialReference().getID() == 102100);
+ // showProjectedGeometryInfo(mapGeom);
+
+ // mapGeom = GeometryEngine.jsonToGeometry(jsonParserCrazy1);
+ // Assert.assertTrue(mapGeom.getSpatialReference().getText().equals(""));
+ // showProjectedGeometryInfo(mapGeom);
+
+ mapGeom = GeometryEngine.jsonToGeometry(jsonParserEnv);
+ Assert.assertTrue(mapGeom.getSpatialReference().getID() == 4326);
+ // showProjectedGeometryInfo(mapGeom);
+
+ try {
+ GeometryEngine.jsonToGeometry(jsonParserInvalidWKID);
+ } catch (Exception ex) {
+ Assert.assertTrue("Should not throw for invalid wkid", false);
+ }
+ }
+
+ @Test
+ public void testMP2onCR175871() throws Exception {
+ Polygon pg = new Polygon();
+ pg.startPath(-50, 10);
+ pg.lineTo(-50, 12);
+ pg.lineTo(-45, 12);
+ pg.lineTo(-45, 10);
+
+ Polygon pg1 = new Polygon();
+ pg1.startPath(-45, 10);
+ pg1.lineTo(-40, 10);
+ pg1.lineTo(-40, 8);
+ pg.add(pg1, false);
+
+ SpatialReference spatialReference = SpatialReference.create(4326);
+
+ try {
+ String jSonStr = GeometryEngine.geometryToJson(spatialReference, pg);
+ JsonFactory jf = new JsonFactory();
+
+ JsonParser jp = jf.createJsonParser(jSonStr);
+ jp.nextToken();
+ MapGeometry mg = GeometryEngine.jsonToGeometry(jp);
+ Geometry gm = mg.getGeometry();
+ Assert.assertEquals(Geometry.Type.Polygon, gm.getType());
+ Assert.assertTrue(mg.getSpatialReference().getID() == 4326);
+
+ Polygon pgNew = (Polygon) gm;
+
+ Assert.assertEquals(pgNew.getPathCount(), pg.getPathCount());
+ Assert.assertEquals(pgNew.getPointCount(), pg.getPointCount());
+ Assert.assertEquals(pgNew.getSegmentCount(), pg.getSegmentCount());
+
+ Assert.assertEquals(pgNew.getPoint(0).getX(), pg.getPoint(0).getX(), 0.000000001);
+ Assert.assertEquals(pgNew.getPoint(1).getX(), pg.getPoint(1).getX(), 0.000000001);
+ Assert.assertEquals(pgNew.getPoint(2).getX(), pg.getPoint(2).getX(), 0.000000001);
+ Assert.assertEquals(pgNew.getPoint(3).getX(), pg.getPoint(3).getX(), 0.000000001);
+
+ Assert.assertEquals(pgNew.getPoint(0).getY(), pg.getPoint(0).getY(), 0.000000001);
+ Assert.assertEquals(pgNew.getPoint(1).getY(), pg.getPoint(1).getY(), 0.000000001);
+ Assert.assertEquals(pgNew.getPoint(2).getY(), pg.getPoint(2).getY(), 0.000000001);
+ Assert.assertEquals(pgNew.getPoint(3).getY(), pg.getPoint(3).getY(), 0.000000001);
+ } catch (Exception ex) {
+ String err = ex.getMessage();
+ System.out.print(err);
+ throw ex;
+ }
+ }
+
+ @Test
+ public static int fromJsonToWkid(JsonParser parser) throws JsonParseException, IOException {
+ int wkid = 0;
+ if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
+ return 0;
+ }
+
+ while (parser.nextToken() != JsonToken.END_OBJECT) {
+ String fieldName = parser.getCurrentName();
+
+ if ("wkid".equals(fieldName)) {
+ parser.nextToken();
+ wkid = parser.getIntValue();
+ }
+ }
+ return wkid;
+ }
+
+ @SuppressWarnings("unused")
+ private static void showProjectedGeometryInfo(MapGeometry mapGeom) {
+ System.out.println("\n");
+ MapGeometry geom = mapGeom;
+ // while ((geom = geomCursor.next()) != null) {
+
+ if (geom.getGeometry() instanceof Point) {
+ Point pnt = (Point) geom.getGeometry();
+ System.out.println("Point(" + pnt.getX() + " , " + pnt.getY() + ")");
+ if (geom.getSpatialReference() == null) {
+ System.out.println("No spatial reference");
+ } else {
+ System.out.println("wkid: " + geom.getSpatialReference().getID());
+ }
+
+ } else if (geom.getGeometry() instanceof MultiPoint) {
+ MultiPoint mp = (MultiPoint) geom.getGeometry();
+ System.out.println("Multipoint has " + mp.getPointCount() + " points.");
+
+ System.out.println("wkid: " + geom.getSpatialReference().getID());
+
+ } else if (geom.getGeometry() instanceof Polygon) {
+ Polygon mp = (Polygon) geom.getGeometry();
+ System.out.println("Polygon has " + mp.getPointCount() + " points and " + mp.getPathCount() + " parts.");
+ if (mp.getPathCount() > 1) {
+ System.out.println("Part start of 2nd segment : " + mp.getPathStart(1));
+ System.out.println("Part end of 2nd segment : " + mp.getPathEnd(1));
+ System.out.println("Part size of 2nd segment : " + mp.getPathSize(1));
+
+ int start = mp.getPathStart(1);
+ int end = mp.getPathEnd(1);
+ for (int i = start; i < end; i++) {
+ Point pp = mp.getPoint(i);
+ System.out.println("Point(" + i + ") = (" + pp.getX() + ", " + pp.getY() + ")");
+ }
+ }
+ System.out.println("wkid: " + geom.getSpatialReference().getID());
+
+ } else if (geom.getGeometry() instanceof Polyline) {
+ Polyline mp = (Polyline) geom.getGeometry();
+ System.out.println("Polyline has " + mp.getPointCount() + " points and " + mp.getPathCount() + " parts.");
+ System.out.println("Part start of 2nd segment : " + mp.getPathStart(1));
+ System.out.println("Part end of 2nd segment : " + mp.getPathEnd(1));
+ System.out.println("Part size of 2nd segment : " + mp.getPathSize(1));
+ int start = mp.getPathStart(1);
+ int end = mp.getPathEnd(1);
+ for (int i = start; i < end; i++) {
+ Point pp = mp.getPoint(i);
+ System.out.println("Point(" + i + ") = (" + pp.getX() + ", " + pp.getY() + ")");
+ }
+
+ System.out.println("wkid: " + geom.getSpatialReference().getID());
+ }
+ }
+
+ @Test
+ public void testGeometryToJSON() {
+ Polygon geom = new Polygon();
+ geom.startPath(new Point(-113, 34));
+ geom.lineTo(new Point(-105, 34));
+ geom.lineTo(new Point(-108, 40));
+
+ String outputPolygon1 = GeometryEngine.geometryToJson(-1, geom);// Test
+ // WKID
+ // == -1
+ // System.out.println("Geom JSON STRING is" + outputPolygon1);
+ String correctPolygon1 = "{\"rings\":[[[-113,34],[-105,34],[-108,40],[-113,34]]]}";
+
+ assertEquals(correctPolygon1, outputPolygon1);
+
+ String outputPolygon2 = GeometryEngine.geometryToJson(4326, geom);
+ // System.out.println("Geom JSON STRING is" + outputPolygon2);
+
+ String correctPolygon2 = "{\"rings\":[[[-113,34],[-105,34],[-108,40],[-113,34]]],\"spatialReference\":{\"wkid\":4326}}";
+ assertEquals(correctPolygon2, outputPolygon2);
+ }
+
+ @Test
+ public void testGeometryToJSONOldID() throws Exception {// CR
+ Polygon geom = new Polygon();
+ geom.startPath(new Point(-113, 34));
+ geom.lineTo(new Point(-105, 34));
+ geom.lineTo(new Point(-108, 40));
+ String outputPolygon = GeometryEngine.geometryToJson(SpatialReference.create(3857), geom);// Test
+ // WKID
+ // ==
+ // -1
+ String correctPolygon = "{\"rings\":[[[-113,34],[-105,34],[-108,40],[-113,34]]],\"spatialReference\":{\"wkid\":102100,\"latestWkid\":3857}}";
+ assertTrue(outputPolygon.equals(correctPolygon));
+ JsonFactory jf = new JsonFactory();
+ JsonParser jp = jf.createJsonParser(outputPolygon);
+ jp.nextToken();
+ MapGeometry mg = GeometryEngine.jsonToGeometry(jp);
+ @SuppressWarnings("unused")
+ int srId = mg.getSpatialReference().getID();
+ @SuppressWarnings("unused")
+ int srOldId = mg.getSpatialReference().getOldID();
+ Assert.assertTrue(mg.getSpatialReference().getID() == 3857);
+ Assert.assertTrue(mg.getSpatialReference().getLatestID() == 3857);
+ Assert.assertTrue(mg.getSpatialReference().getOldID() == 102100);
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestMathUtils.java b/src/test/java/com/esri/core/geometry/TestMathUtils.java
similarity index 53%
rename from unittest/com/esri/core/geometry/TestMathUtils.java
rename to src/test/java/com/esri/core/geometry/TestMathUtils.java
index 0d41a739..c6d39735 100644
--- a/unittest/com/esri/core/geometry/TestMathUtils.java
+++ b/src/test/java/com/esri/core/geometry/TestMathUtils.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
diff --git a/unittest/com/esri/core/geometry/TestMultiPoint.java b/src/test/java/com/esri/core/geometry/TestMultiPoint.java
similarity index 85%
rename from unittest/com/esri/core/geometry/TestMultiPoint.java
rename to src/test/java/com/esri/core/geometry/TestMultiPoint.java
index 44c927f6..cd8e8d70 100644
--- a/unittest/com/esri/core/geometry/TestMultiPoint.java
+++ b/src/test/java/com/esri/core/geometry/TestMultiPoint.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
@@ -77,35 +101,9 @@ public static void testCreation() {
MultiPoint mpoint = new MultiPoint();
assertTrue(mpoint != null);
- // FIXME uncomment when assertions are fixed
- // try
- // {
- // // OutputDebugString(L"Test an assert\n");
- // // GeometryException::m_assertOnException = false;
- //
- // Point pt2 = mpoint.getPoint(0);;
- // }
- // catch(GeometryException except)
- // {
- // assertTrue(except.index_out_of_bounds);
- // GeometryException::m_assertOnException = true;
- // }
MultiPoint mpoint1 = new MultiPoint();
assertTrue(mpoint1 != null);
- // FIXME uncomment when assertions are fixed
- // try
- // {
- // OutputDebugString(L"Test an assert\n");
- // GeometryException::m_assertOnException = false;
- // Point ppp;
- // mpoint.getPointByVal(0, ppp);
- // }
- // catch(GeometryException except)
- // {
- // assertTrue(except.index_out_of_bounds);
- // GeometryException::m_assertOnException = true;
- // }
mpoint.setEmpty();
Point pt = new Point(0, 0);
@@ -129,20 +127,6 @@ public static void testCreation() {
mpoint.add(pt);
Point pt3 = mpoint.getPoint(0);
assertTrue(pt3.getX() == 0 && pt3.getY() == 0/* && pt3.getZ() == 0 */);
- // assertFalse(mpoint->HasAttribute(VertexDescription::Semantics::Z));
- // FIXME once transform3D is public
- // Transformation3D transform3D = GCNEW Transformation3D;
- // transform3D.setTranslate(1, 1, 0);
- // mpoint.applyTransformation(transform3D);
-
- // assertTrue(mpoint->HasAttribute(VertexDescription::Semantics::Z));
- // pt3 = mpoint.getPoint(0);
- // assertTrue(pt3.x == 1 && pt3.y == 1 && pt3.z == 0);
- // transform3D.setTranslate(56, 12, 333);
- // mpoint.applyTransformation(transform3D);
- // pt3 = mpoint.getXYZ(0);
- // assertTrue(pt3.x == 57 && pt3.y == 13 && pt3.z == 333);
- // CompareGeometryContent(mpoint, &pt3, 1);
}
{ // test QueryInterval
diff --git a/unittest/com/esri/core/geometry/TestOGC.java b/src/test/java/com/esri/core/geometry/TestOGC.java
similarity index 53%
rename from unittest/com/esri/core/geometry/TestOGC.java
rename to src/test/java/com/esri/core/geometry/TestOGC.java
index 218ebdc3..b68f2fcc 100644
--- a/unittest/com/esri/core/geometry/TestOGC.java
+++ b/src/test/java/com/esri/core/geometry/TestOGC.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
@@ -6,14 +30,14 @@
import com.esri.core.geometry.ogc.OGCGeometryCollection;
import com.esri.core.geometry.ogc.OGCLineString;
import com.esri.core.geometry.ogc.OGCMultiCurve;
+import com.esri.core.geometry.ogc.OGCMultiLineString;
import com.esri.core.geometry.ogc.OGCMultiPoint;
import com.esri.core.geometry.ogc.OGCMultiPolygon;
import com.esri.core.geometry.ogc.OGCPoint;
import com.esri.core.geometry.ogc.OGCPolygon;
import com.esri.core.geometry.ogc.OGCConcreteGeometryCollection;
-import org.codehaus.jackson.JsonParseException;
-import org.json.JSONException;
+import org.junit.Test;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -29,6 +53,7 @@ protected void tearDown() throws Exception {
super.tearDown();
}
+ @Test
public void testPoint() {
OGCGeometry g = OGCGeometry.fromText("POINT(1 2)");
assertTrue(g.geometryType().equals("Point"));
@@ -37,6 +62,8 @@ public void testPoint() {
assertTrue(p.Y() == 2);
assertTrue(g.equals(OGCGeometry.fromText("POINT(1 2)")));
assertTrue(!g.equals(OGCGeometry.fromText("POINT(1 3)")));
+ assertTrue(g.equals((Object)OGCGeometry.fromText("POINT(1 2)")));
+ assertTrue(!g.equals((Object)OGCGeometry.fromText("POINT(1 3)")));
OGCGeometry buf = g.buffer(10);
assertTrue(buf.geometryType().equals("Polygon"));
OGCPolygon poly = (OGCPolygon) buf.envelope();
@@ -44,29 +71,51 @@ public void testPoint() {
assertTrue(Math.abs(a - 400) < 1e-1);
}
- public void testPolygon() {
+ @Test
+ public void testPolygon() throws Exception {
OGCGeometry g = OGCGeometry
.fromText("POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5))");
assertTrue(g.geometryType().equals("Polygon"));
OGCPolygon p = (OGCPolygon) g;
assertTrue(p.numInteriorRing() == 1);
- OGCLineString ls = p.exterorRing();
+ OGCLineString ls = p.exteriorRing();
// assertTrue(ls.pointN(1).equals(OGCGeometry.fromText("POINT(10 -10)")));
boolean b = ls
- .equals(OGCGeometry
+ .Equals(OGCGeometry
.fromText("LINESTRING(-10 -10, 10 -10, 10 10, -10 10, -10 -10)"));
assertTrue(b);
OGCLineString lsi = p.interiorRingN(0);
- b = lsi.equals(OGCGeometry
+ b = lsi.Equals(OGCGeometry
.fromText("LINESTRING(-5 -5, -5 5, 5 5, 5 -5, -5 -5)"));
assertTrue(b);
- assertTrue(!lsi.equals(ls));
+ b = lsi.equals((Object)OGCGeometry
+ .fromText("LINESTRING(-5 -5, -5 5, 5 5, 5 -5, -5 -5)"));
+ assertTrue(!lsi.Equals(ls));
OGCMultiCurve boundary = p.boundary();
String s = boundary.asText();
assertTrue(s.equals("MULTILINESTRING ((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5))"));
+
+ {
+ OGCGeometry g2 = OGCGeometry.fromGeoJson(
+ "{\"type\": \"Polygon\", \"coordinates\": [[[1.00000001,1.00000001], [4.00000001,1.00000001], [4.00000001,4.00000001], [1.00000001,4.00000001]]]}");
+ OGCGeometry
+ .fromGeoJson(
+ "{\"type\": \"LineString\", \"coordinates\": [[1.00000001,1.00000001], [7.00000001,8.00000001]]}")
+ .intersects(g2);
+ OGCGeometry
+ .fromGeoJson(
+ "{\"type\": \"LineString\", \"coordinates\": [[2.449,4.865], [7.00000001,8.00000001]]}")
+ .intersects(g2);
+
+ OGCGeometry g3 = OGCGeometry.fromGeoJson(
+ "{\"type\": \"Polygon\", \"coordinates\": [[[1.00000001,1.00000001], [4.00000001,1.00000001], [4.00000001,4.00000001], [1.00000001,4.00000001]]]}");
+ boolean bb = g2.equals((Object) g3);
+ assertTrue(bb);
+ }
}
- public void testGeometryCollection() throws JSONException {
+ @Test
+ public void testGeometryCollection() throws Exception {
OGCGeometry g = OGCGeometry
.fromText("GEOMETRYCOLLECTION(POLYGON EMPTY, POINT(1 1), LINESTRING EMPTY, MULTIPOLYGON EMPTY, MULTILINESTRING EMPTY)");
assertTrue(g.geometryType().equals("GeometryCollection"));
@@ -134,25 +183,33 @@ public void testGeometryCollection() throws JSONException {
wktString = g.asText();
assertTrue(wktString
.equals("GEOMETRYCOLLECTION (POLYGON EMPTY, POINT (1 1), GEOMETRYCOLLECTION EMPTY, LINESTRING EMPTY, GEOMETRYCOLLECTION (POLYGON EMPTY, POINT (1 1), LINESTRING EMPTY, MULTIPOLYGON EMPTY, MULTILINESTRING EMPTY, MULTIPOINT EMPTY), MULTIPOLYGON EMPTY, MULTILINESTRING EMPTY)"));
+
+ assertTrue(g.equals((Object)OGCGeometry.fromText(wktString)));
+
+ assertTrue(g.hashCode() == OGCGeometry.fromText(wktString).hashCode());
}
+ @Test
public void testFirstPointOfPolygon() {
OGCGeometry g = OGCGeometry
.fromText("POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5))");
assertTrue(g.geometryType().equals("Polygon"));
OGCPolygon p = (OGCPolygon) g;
assertTrue(p.numInteriorRing() == 1);
- OGCLineString ls = p.exterorRing();
+ OGCLineString ls = p.exteriorRing();
OGCPoint p1 = ls.pointN(1);
assertTrue(ls.pointN(1).equals(OGCGeometry.fromText("POINT(10 -10)")));
OGCPoint p2 = ls.pointN(3);
assertTrue(ls.pointN(3).equals(OGCGeometry.fromText("POINT(-10 10)")));
OGCPoint p0 = ls.pointN(0);
assertTrue(ls.pointN(0).equals(OGCGeometry.fromText("POINT(-10 -10)")));
+ String ms = g.convertToMulti().asText();
+ assertTrue(ms.equals("MULTIPOLYGON (((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5)))"));
}
+ @Test
public void testFirstPointOfLineString() {
OGCGeometry g = OGCGeometry
.fromText("LINESTRING(-10 -10, 10 -10, 10 10, -10 10, -10 -10)");
@@ -161,8 +218,11 @@ public void testFirstPointOfLineString() {
assertTrue(p.numPoints() == 5);
assertTrue(p.isClosed());
assertTrue(p.pointN(1).equals(OGCGeometry.fromText("POINT(10 -10)")));
+ String ms = g.convertToMulti().asText();
+ assertTrue(ms.equals("MULTILINESTRING ((-10 -10, 10 -10, 10 10, -10 10, -10 -10))"));
}
+ @Test
public void testPointInPolygon() {
OGCGeometry g = OGCGeometry
.fromText("POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5))");
@@ -173,22 +233,43 @@ public void testPointInPolygon() {
assertTrue(g.disjoint(OGCGeometry.fromText("POINT(0 0)")));
assertTrue(!g.disjoint(OGCGeometry.fromText("POINT(9 9)")));
assertTrue(g.disjoint(OGCGeometry.fromText("POINT(-20 1)")));
-
}
+ @Test
public void testMultiPolygon() {
- OGCGeometry g = OGCGeometry
- .fromText("MULTIPOLYGON(((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5)))");
- assertTrue(g.geometryType().equals("MultiPolygon")); // the type is
- // reduced
- assertTrue(!g.contains(OGCGeometry.fromText("POINT(0 0)")));
- assertTrue(g.contains(OGCGeometry.fromText("POINT(9 9)")));
- assertTrue(!g.contains(OGCGeometry.fromText("POINT(-20 1)")));
- assertTrue(g.disjoint(OGCGeometry.fromText("POINT(0 0)")));
- assertTrue(!g.disjoint(OGCGeometry.fromText("POINT(9 9)")));
- assertTrue(g.disjoint(OGCGeometry.fromText("POINT(-20 1)")));
+ {
+ OGCGeometry g = OGCGeometry
+ .fromText("MULTIPOLYGON(((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5)))");
+ assertTrue(g.geometryType().equals("MultiPolygon")); // the type is
+ // reduced
+ assertTrue(!g.contains(OGCGeometry.fromText("POINT(0 0)")));
+ assertTrue(g.contains(OGCGeometry.fromText("POINT(9 9)")));
+ assertTrue(!g.contains(OGCGeometry.fromText("POINT(-20 1)")));
+ assertTrue(g.disjoint(OGCGeometry.fromText("POINT(0 0)")));
+ assertTrue(!g.disjoint(OGCGeometry.fromText("POINT(9 9)")));
+ assertTrue(g.disjoint(OGCGeometry.fromText("POINT(-20 1)")));
+ assertTrue(g.convertToMulti() == g);
+ }
+
+ {
+ OGCGeometry g = OGCGeometry
+ .fromText("MULTIPOLYGON(((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5)), ((90 90, 110 90, 110 110, 90 110, 90 90), (95 95, 95 105, 105 105, 105 95, 95 95)))");
+ assertTrue(g.geometryType().equals("MultiPolygon")); // the type is
+
+ OGCMultiPolygon mp = (OGCMultiPolygon)g;
+ assertTrue(mp.numGeometries() == 2);
+ OGCGeometry p1 = mp.geometryN(0);
+ assertTrue(p1.geometryType().equals("Polygon")); // the type is
+ assertTrue(p1.contains(OGCGeometry.fromText("POINT(9 9)")));
+ assertTrue(!p1.contains(OGCGeometry.fromText("POINT(109 109)")));
+ OGCGeometry p2 = mp.geometryN(1);
+ assertTrue(p2.geometryType().equals("Polygon")); // the type is
+ assertTrue(!p2.contains(OGCGeometry.fromText("POINT(9 9)")));
+ assertTrue(p2.contains(OGCGeometry.fromText("POINT(109 109)")));
+ }
}
+ @Test
public void testMultiPolygonUnion() {
OGCGeometry g = OGCGeometry
.fromText("POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5))");
@@ -205,6 +286,7 @@ public void testMultiPolygonUnion() {
assertTrue(u.contains(OGCGeometry.fromText("POINT(100 100)")));
}
+ @Test
public void testIntersection() {
OGCGeometry g = OGCGeometry.fromText("LINESTRING(0 0, 10 10)");
OGCGeometry g2 = OGCGeometry.fromText("LINESTRING(10 0, 0 10)");
@@ -214,6 +296,7 @@ public void testIntersection() {
assertTrue(u.equals(OGCGeometry.fromText("POINT(5 5)")));
}
+ @Test
public void testPointSymDif() {
OGCGeometry g1 = OGCGeometry.fromText("POINT(1 2)");
OGCGeometry g2 = OGCGeometry.fromText("POINT(3 4)");
@@ -226,6 +309,7 @@ public void testPointSymDif() {
}
+ @Test
public void testNullSr() {
String wkt = "point (0 0)";
OGCGeometry g = OGCGeometry.fromText(wkt);
@@ -233,6 +317,7 @@ public void testNullSr() {
assertTrue(g.SRID() < 1);
}
+ @Test
public void testIsectPoint() {
String wkt = "point (0 0)";
String wk2 = "point (0 0)";
@@ -248,6 +333,7 @@ public void testIsectPoint() {
}
}
+ @Test
public void testIsectDisjoint() {
String wk3 = "linestring (0 0, 1 1)";
String wk4 = "linestring (2 2, 4 4)";
@@ -263,6 +349,7 @@ public void testIsectDisjoint() {
}
}
+ @Test
public void test_polygon_is_simple_for_OGC() {
try {
{
@@ -372,10 +459,20 @@ public void test_polygon_is_simple_for_OGC() {
}
}
- /*
- This will fail
+ @Test
public void test_polygon_simplify_for_OGC() {
try {
+ {
+ //degenerate
+ String s = "{\"rings\":[[[0, 0], [0, 10], [10, 10], [10, 0], [20, 0], [10, 0], [0, 0]]]}";
+ OGCGeometry g = OGCGeometry.fromJson(s);
+ boolean res = g.isSimple();
+ assertTrue(!res);
+ Geometry resg = OperatorSimplifyOGC.local().execute(g.getEsriGeometry(), null, true, null);
+ OGCGeometry og = OGCGeometry.createFromEsriGeometry(resg, null);
+ String res_str = og.asText();
+ assertTrue(og.isSimple());
+ }
{
String s = "{\"rings\":[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]}";
OGCGeometry g = OGCGeometry.fromJson(s);
@@ -384,8 +481,10 @@ public void test_polygon_simplify_for_OGC() {
assertTrue(g.isSimpleRelaxed());
Geometry resg = OperatorSimplifyOGC.local().execute(g.getEsriGeometry(), null, true, null);
OGCGeometry og = OGCGeometry.createFromEsriGeometry(resg, null);
+ String res_str = og.asText();
assertTrue(og.geometryType().equals("Polygon"));
assertTrue(((OGCPolygon)og).numInteriorRing() == 0);
+ assertTrue(og.isSimple());
}
{// exterior ring is self-tangent
@@ -438,6 +537,7 @@ public void test_polygon_simplify_for_OGC() {
assertTrue(g.isSimpleRelaxed());
Geometry resg = OperatorSimplifyOGC.local().execute(g.getEsriGeometry(), null, true, null);
OGCGeometry og = OGCGeometry.createFromEsriGeometry(resg, null);
+ String res_str = og.asText();
res = og.isSimple();
assertTrue(res);
assertTrue(og.geometryType().equals("Polygon"));
@@ -528,12 +628,34 @@ public void test_polygon_simplify_for_OGC() {
assertTrue(((OGCPolygon)((OGCMultiPolygon)og).geometryN(0)).numInteriorRing() == 0);
assertTrue(((OGCPolygon)((OGCMultiPolygon)og).geometryN(1)).numInteriorRing() == 0);
}
+
+
+ {
+ OGCGeometry g = OGCGeometry.fromJson("{\"rings\":[[[-3,4],[6,4],[6,-3],[-3,-3],[-3,4]],[[0,2],[2,2],[0,0],[4,0],[4,2],[2,0],[2,2],[4,2],[3,3],[2,2],[1,3],[0,2]]], \"spatialReference\":{\"wkid\":4326}}");
+ assertTrue(g.geometryType().equals("Polygon"));
+ boolean res = g.isSimple();
+ assertTrue(!res);
+ assertTrue(!g.isSimpleRelaxed());
+ OGCGeometry simpleG = g.makeSimple();
+ assertTrue(simpleG.geometryType().equals("MultiPolygon"));
+ assertTrue(simpleG.isSimple());
+ OGCMultiPolygon mp = (OGCMultiPolygon)simpleG;
+ assertTrue(mp.numGeometries() == 2);
+ OGCPolygon g1 = (OGCPolygon)mp.geometryN(0);
+ OGCPolygon g2 = (OGCPolygon)mp.geometryN(1);
+ assertTrue((g1.numInteriorRing() == 0 && g1.numInteriorRing() == 2) ||
+ (g1.numInteriorRing() == 2 && g2.numInteriorRing() == 0));
+
+ OGCGeometry oldOutput = OGCGeometry.fromJson("{\"rings\":[[[-3,-3],[-3,4],[6,4],[6,-3],[-3,-3]],[[0,0],[2,0],[4,0],[4,2],[3,3],[2,2],[1,3],[0,2],[2,2],[0,0]],[[2,0],[2,2],[4,2],[2,0]]],\"spatialReference\":{\"wkid\":4326}}");
+ assertTrue(oldOutput.isSimpleRelaxed());
+ assertFalse(oldOutput.isSimple());
+ }
} catch (Exception ex) {
assertTrue(false);
}
}
- */
+ @Test
public void test_polyline_is_simple_for_OGC() {
try {
{
@@ -635,6 +757,7 @@ public void test_polyline_is_simple_for_OGC() {
}
+ @Test
public void test_multipoint_is_simple_for_OGC() {
try {
@@ -667,6 +790,7 @@ public void test_multipoint_is_simple_for_OGC() {
}
+ @Test
public void testGeometryCollectionBuffer() {
OGCGeometry g = OGCGeometry
.fromText("GEOMETRYCOLLECTION(POINT(1 1), POINT(1 1), POINT(1 2), LINESTRING (0 0, 1 1, 1 0, 0 1), MULTIPOLYGON EMPTY, MULTILINESTRING EMPTY)");
@@ -676,19 +800,35 @@ public void testGeometryCollectionBuffer() {
assertTrue(simpleG.geometryType().equals("GeometryCollection"));
}
+ @Test
public void testIsectTria1() {
String wkt = "polygon((1 0, 3 0, 1 2, 1 0))";
String wk2 = "polygon((0 1, 2 1, 0 3, 0 1))";
OGCGeometry g0 = OGCGeometry.fromText(wkt);
OGCGeometry g1 = OGCGeometry.fromText(wk2);
- g0.setSpatialReference(null);
- g1.setSpatialReference(null);
+ g0.setSpatialReference(SpatialReference.create(4326));
+ g1.setSpatialReference(SpatialReference.create(4326));
OGCGeometry rslt = g0.intersection(g1);
assertTrue(rslt != null);
assertTrue(rslt.geometryType().equals("Polygon"));
+ assertTrue(rslt.esriSR.getID() == 4326);
String s = rslt.asText();
}
+ @Test
+ public void testIsectTriaJson1() throws Exception {
+ String json1 = "{\"rings\":[[[1, 0], [3, 0], [1, 2], [1, 0]]], \"spatialReference\":{\"wkid\":4326}}";
+ String json2 = "{\"rings\":[[[0, 1], [2, 1], [0, 3], [0, 1]]], \"spatialReference\":{\"wkid\":4326}}";
+ OGCGeometry g0 = OGCGeometry.fromJson(json1);
+ OGCGeometry g1 = OGCGeometry.fromJson(json2);
+ OGCGeometry rslt = g0.intersection(g1);
+ assertTrue(rslt != null);
+ assertTrue(rslt.geometryType().equals("Polygon"));
+ assertTrue(rslt.esriSR.getID() == 4326);
+ String s = GeometryEngine.geometryToJson(rslt.getEsriSpatialReference().getID(), rslt.getEsriGeometry());
+ }
+
+ @Test
public void testIsectTria2() {
String wkt = "polygon((1 0, 3 0, 1 2, 1 0))";
String wk2 = "polygon((0 3, 2 1, 3 1, 0 3))";
@@ -703,20 +843,23 @@ public void testIsectTria2() {
String s = rslt.asText();
}
+ @Test
public void testIsectTria3() {
String wkt = "polygon((1 0, 3 0, 1 2, 1 0))";
String wk2 = "polygon((2 2, 2 1, 3 1, 2 2))";
OGCGeometry g0 = OGCGeometry.fromText(wkt);
OGCGeometry g1 = OGCGeometry.fromText(wk2);
- g0.setSpatialReference(null);
- g1.setSpatialReference(null);
+ g0.setSpatialReference(SpatialReference.create(4326));
+ g1.setSpatialReference(SpatialReference.create(4326));
OGCGeometry rslt = g0.intersection(g1);
assertTrue(rslt != null);
assertTrue(rslt.dimension() == 0);
assertTrue(rslt.geometryType().equals("Point"));
+ assertTrue(rslt.esriSR.getID() == 4326);
String s = rslt.asText();
}
+ @Test
public void testMultiPointSinglePoint() {
String wkt = "multipoint((1 0))";
OGCGeometry g0 = OGCGeometry.fromText(wkt);
@@ -728,22 +871,189 @@ public void testMultiPointSinglePoint() {
OGCGeometry p = mp.geometryN(0);
String s = p.asText();
assertTrue(s.equals("POINT (1 0)"));
+
+ String ms = p.convertToMulti().asText();
+ assertTrue(ms.equals("MULTIPOINT ((1 0))"));
+
}
+ @Test
public void testWktMultiPolygon() {
String restJson = "{\"rings\": [[[-100, -100], [-100, 100], [100, 100], [100, -100], [-100, -100]], [[-90, -90], [90, 90], [-90, 90], [90, -90], [-90, -90]], [[-10, -10], [-10, 10], [10, 10], [10, -10], [-10, -10]]]}";
MapGeometry g = null;
- try {
- g = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, restJson);
- } catch (JsonParseException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ g = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, restJson);
String wkt = OperatorExportToWkt.local().execute(0, g.getGeometry(), null);
assertTrue(wkt.equals("MULTIPOLYGON (((-100 -100, 100 -100, 100 100, -100 100, -100 -100), (-90 -90, 90 -90, -90 90, 90 90, -90 -90)), ((-10 -10, 10 -10, 10 10, -10 10, -10 -10)))"));
}
+
+ @Test
+ public void testMultiPolygonArea() {
+ //MultiPolygon Area #36
+ String wkt = "MULTIPOLYGON (((1001200 2432900, 1001420 2432691, 1001250 2432388, 1001498 2432325, 1001100 2432100, 1001500 2431900, 1002044 2431764, 1002059 2432120, 1002182 2432003, 1002400 2432300, 1002650 2432150, 1002610 2432323, 1002772 2432434, 1002410 2432821, 1002700 2433000, 1001824 2432866, 1001600 2433150, 1001200 2432900)), ((1000393 2433983, 1000914 2434018, 1000933 2433817, 1000568 2433834, 1000580 2433584, 1000700 2433750, 1000800 2433650, 1000700 2433450, 1000600 2433550, 1000200 2433350, 1000100 2433900, 1000393 2433983)), ((1001200 2432900, 1000878 2432891, 1000900 2433300, 1001659 2433509, 1001600 2433150, 1001200 2432900)), ((1002450 2431650, 1002300 2431650, 1002300 2431900, 1002500 2432100, 1002600 2431800, 1002450 2431800, 1002450 2431650)), ((999750 2433550, 999850 2433600, 999900 2433350, 999780 2433433, 999750 2433550)), ((1002950 2432050, 1003005 2431932, 1002850 2432250, 1002928 2432210, 1002950 2432050)), ((1002600 2431750, 1002642 2431882, 1002750 2431900, 1002750 2431750, 1002600 2431750)), ((1002950 2431750, 1003050 2431650, 1002968 2431609, 1002950 2431750)))";
+ {
+ OGCGeometry ogcg = OGCGeometry.fromText(wkt);
+ assertTrue(ogcg.geometryType().equals("MultiPolygon"));
+ OGCMultiPolygon mp = (OGCMultiPolygon)ogcg;
+ double a = mp.area();
+ assertTrue(Math.abs(mp.area() - 2037634.5) < a*1e-14);
+ }
+
+ {
+ OGCGeometry ogcg = OGCGeometry.fromText(wkt);
+ assertTrue(ogcg.geometryType().equals("MultiPolygon"));
+ Geometry g = ogcg.getEsriGeometry();
+ double a = g.calculateArea2D();
+ assertTrue(Math.abs(a - 2037634.5) < a*1e-14);
+ }
+ }
+
+ @Test
+ public void testPolylineSimplifyIssueGithub52() throws Exception {
+ String json = "{\"paths\":[[[2,0],[4,3],[5,1],[3.25,1.875],[1,3]]],\"spatialReference\":{\"wkid\":4326}}";
+ {
+ OGCGeometry g = OGCGeometry.fromJson(json);
+ assertTrue(g.geometryType().equals("LineString"));
+ OGCGeometry simpleG = g.makeSimple();//make ogc simple
+ assertTrue(simpleG.geometryType().equals("MultiLineString"));
+ assertTrue(simpleG.isSimpleRelaxed());//geodatabase simple
+ assertTrue(simpleG.isSimple());//ogc simple
+ OGCMultiLineString mls =(OGCMultiLineString)simpleG;
+ assertTrue(mls.numGeometries() == 4);
+ OGCGeometry baseGeom = OGCGeometry.fromJson("{\"paths\":[[[2,0],[3.25,1.875]],[[3.25,1.875],[4,3],[5,1]],[[5,1],[3.25,1.875]],[[3.25,1.875],[1,3]]],\"spatialReference\":{\"wkid\":4326}}");
+ assertTrue(simpleG.equals(baseGeom));
+
+ }
+ }
+
+ @Test
+ public void testEmptyBoundary() throws Exception {
+ {
+ OGCGeometry g = OGCGeometry.fromText("POINT EMPTY");
+ OGCGeometry b = g.boundary();
+ assertTrue(b.asText().compareTo("MULTIPOINT EMPTY") == 0);
+ }
+ {
+ OGCGeometry g = OGCGeometry.fromText("MULTIPOINT EMPTY");
+ OGCGeometry b = g.boundary();
+ assertTrue(b.asText().compareTo("MULTIPOINT EMPTY") == 0);
+ }
+ {
+ OGCGeometry g = OGCGeometry.fromText("LINESTRING EMPTY");
+ OGCGeometry b = g.boundary();
+ assertTrue(b.asText().compareTo("MULTIPOINT EMPTY") == 0);
+ }
+ {
+ OGCGeometry g = OGCGeometry.fromText("POLYGON EMPTY");
+ OGCGeometry b = g.boundary();
+ assertTrue(b.asText().compareTo("MULTILINESTRING EMPTY") == 0);
+ }
+ {
+ OGCGeometry g = OGCGeometry.fromText("MULTIPOLYGON EMPTY");
+ OGCGeometry b = g.boundary();
+ assertTrue(b.asText().compareTo("MULTILINESTRING EMPTY") == 0);
+ }
+ }
+
+ @Test
+ public void testUnionPointWithEmptyLineString() {
+ assertUnion("POINT (1 2)", "LINESTRING EMPTY", "POINT (1 2)");
+ }
+
+ @Test
+ public void testUnionPointWithLinestring() {
+ assertUnion("POINT (1 2)", "LINESTRING (3 4, 5 6)", "GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6))");
+ }
+
+ @Test
+ public void testUnionLinestringWithEmptyPolygon() {
+ assertUnion("MULTILINESTRING ((1 2, 3 4))", "POLYGON EMPTY", "LINESTRING (1 2, 3 4)");
+ }
+
+ @Test
+ public void testUnionLinestringWithPolygon() {
+ assertUnion("LINESTRING (1 2, 3 4)", "POLYGON ((0 0, 1 1, 0 1, 0 0))",
+ "GEOMETRYCOLLECTION (LINESTRING (1 2, 3 4), POLYGON ((0 0, 1 1, 0 1, 0 0)))");
+ }
+
+ @Test
+ public void testUnionGeometryCollectionWithGeometryCollection() {
+ assertUnion("GEOMETRYCOLLECTION (LINESTRING (1 2, 3 4), POLYGON ((0 0, 1 1, 0 1, 0 0)))",
+ "GEOMETRYCOLLECTION (POINT (1 2), POINT (2 3), POINT (0.5 0.5), POINT (3 5), LINESTRING (3 4, 5 6), POLYGON ((0 0, 1 0, 1 1, 0 0)))",
+ "GEOMETRYCOLLECTION (POINT (3 5), LINESTRING (1 2, 2 3, 3 4, 5 6), POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)))");
+ }
+
+ @Test
+ public void testIntersectionGeometryCollectionWithGeometryCollection() {
+ assertIntersection("GEOMETRYCOLLECTION (LINESTRING (1 2, 3 4), POLYGON ((0 0, 1 1, 0 1, 0 0)))",
+ "GEOMETRYCOLLECTION (POINT (1 2), POINT (2 3), POINT (0.5 0.5), POINT (3 5), LINESTRING (3 4, 5 6), POLYGON ((0 0, 1 0, 1 1, 0 0)))",
+ "GEOMETRYCOLLECTION (MULTIPOINT ((1 2), (2 3), (3 4)), LINESTRING (0 0, 0.5 0.5, 1 1))");
+ }
+
+ private void assertIntersection(String leftWkt, String rightWkt, String expectedWkt) {
+ OGCGeometry intersection = OGCGeometry.fromText(leftWkt).intersection(OGCGeometry.fromText(rightWkt));
+ assertEquals(expectedWkt, intersection.asText());
+ }
+
+ private void assertUnion(String leftWkt, String rightWkt, String expectedWkt) {
+ OGCGeometry union = OGCGeometry.fromText(leftWkt).union(OGCGeometry.fromText(rightWkt));
+ assertEquals(expectedWkt, union.asText());
+ }
+
+ @Test
+ public void testDisjointOnGeometryCollection() {
+ OGCGeometry ogcGeometry = OGCGeometry.fromText("GEOMETRYCOLLECTION (POINT (1 1))");
+ assertFalse(ogcGeometry.disjoint(OGCGeometry.fromText("POINT (1 1)")));
+ }
+
+ @Test
+ public void testContainsOnGeometryCollection() {
+ OGCGeometry ogcGeometry = OGCGeometry.fromText("GEOMETRYCOLLECTION (POINT (1 1))");
+ assertTrue(ogcGeometry.contains(OGCGeometry.fromText("POINT (1 1)")));
+ }
+
+ @Test
+ public void testIntersectsOnGeometryCollection() {
+ OGCGeometry ogcGeometry = OGCGeometry.fromText("GEOMETRYCOLLECTION (POINT (1 1))");
+ assertTrue(ogcGeometry.intersects(OGCGeometry.fromText("POINT (1 1)")));
+ ogcGeometry = OGCGeometry.fromText("POINT (1 1)");
+ assertTrue(ogcGeometry.intersects(OGCGeometry.fromText("GEOMETRYCOLLECTION (POINT (1 1))")));
+ }
+
+ @Test
+ public void testDistanceOnGeometryCollection() {
+ OGCGeometry ogcGeometry = OGCGeometry.fromText("GEOMETRYCOLLECTION (POINT (1 1))");
+ assertTrue(ogcGeometry.distance(OGCGeometry.fromText("POINT (1 1)")) == 0);
+
+ //distance to empty is NAN
+ ogcGeometry = OGCGeometry.fromText("GEOMETRYCOLLECTION (POINT (1 1))");
+ assertTrue(Double.isNaN(ogcGeometry.distance(OGCGeometry.fromText("POINT EMPTY"))));
+ }
+
+ @Test
+ public void testFlattened() {
+ OGCConcreteGeometryCollection ogcGeometry = (OGCConcreteGeometryCollection)OGCGeometry.fromText("GEOMETRYCOLLECTION (MULTILINESTRING ((1 2, 3 4)), MULTIPOLYGON (((1 2, 3 4, 5 6, 1 2))), MULTIPOINT (1 1))");
+ assertFalse(ogcGeometry.isFlattened());
+ ogcGeometry = (OGCConcreteGeometryCollection)OGCGeometry.fromText("GEOMETRYCOLLECTION (MULTIPOINT (1 1), MULTILINESTRING ((1 2, 3 4)), MULTIPOLYGON (((1 2, 3 4, 5 6, 1 2))))");
+ assertTrue(ogcGeometry.isFlattened());
+ }
+
+ @Test
+ public void testIssue247IsSimple() {
+ //https://github.com/Esri/geometry-api-java/issues/247
+ String wkt = "MULTILINESTRING ((-103.4894322 25.6164519, -103.4889647 25.6159054, -103.489434 25.615654), (-103.489434 25.615654, -103.4894322 25.6164519), (-103.4897361 25.6168342, -103.4894322 25.6164519))";
+ OGCGeometry ogcGeom = OGCGeometry.fromText(wkt);
+ boolean b = ogcGeom.isSimple();
+ assertTrue(b);
+ }
+
+ @Test
+ public void testOGCUnionLinePoint() {
+ OGCGeometry point = OGCGeometry.fromText("POINT (-44.16176186699087 -19.943264803833348)");
+ OGCGeometry lineString = OGCGeometry.fromText(
+ "LINESTRING (-44.1247493 -19.9467657, -44.1247979 -19.9468385, -44.1249043 -19.946934, -44.1251096 -19.9470651, -44.1252609 -19.9471383, -44.1254992 -19.947204, -44.1257652 -19.947229, -44.1261292 -19.9471833, -44.1268946 -19.9470098, -44.1276847 -19.9468416, -44.127831 -19.9468143, -44.1282639 -19.9467366, -44.1284569 -19.9467237, -44.1287119 -19.9467261, -44.1289437 -19.9467665, -44.1291499 -19.9468221, -44.1293856 -19.9469396, -44.1298857 -19.9471497, -44.1300908 -19.9472071, -44.1302743 -19.9472331, -44.1305029 -19.9472364, -44.1306498 -19.9472275, -44.1308054 -19.947216, -44.1308553 -19.9472037, -44.1313206 -19.9471394, -44.1317889 -19.9470854, -44.1330422 -19.9468887, -44.1337465 -19.9467083, -44.1339922 -19.9466842, -44.1341506 -19.9466997, -44.1343621 -19.9467226, -44.1345134 -19.9467855, -44.1346494 -19.9468456, -44.1347295 -19.946881, -44.1347988 -19.9469299, -44.1350231 -19.9471131, -44.1355843 -19.9478307, -44.1357802 -19.9480557, -44.1366289 -19.949198, -44.1370384 -19.9497001, -44.137386 -19.9501921, -44.1374113 -19.9502263, -44.1380888 -19.9510925, -44.1381769 -19.9513526, -44.1382509 -19.9516202, -44.1383014 -19.9522136, -44.1383889 -19.9530931, -44.1384227 -19.9538784, -44.1384512 -19.9539653, -44.1384555 -19.9539807, -44.1384901 -19.9541928, -44.1385563 -19.9543859, -44.1386656 -19.9545781, -44.1387339 -19.9546889, -44.1389219 -19.9548661, -44.1391695 -19.9550384, -44.1393672 -19.9551414, -44.1397538 -19.9552208, -44.1401714 -19.9552332, -44.1405656 -19.9551143, -44.1406198 -19.9550853, -44.1407579 -19.9550224, -44.1409029 -19.9549201, -44.1410283 -19.9548257, -44.1413902 -19.9544132, -44.141835 -19.9539274, -44.142268 -19.953484, -44.1427036 -19.9531023, -44.1436229 -19.952259, -44.1437568 -19.9521565, -44.1441783 -19.9517273, -44.144644 -19.9512109, -44.1452538 -19.9505663, -44.1453541 -19.9504774, -44.1458653 -19.9500442, -44.1463563 -19.9496473, -44.1467534 -19.9492812, -44.1470553 -19.9490028, -44.1475804 -19.9485293, -44.1479838 -19.9482096, -44.1485003 -19.9478532, -44.1489451 -19.9477314, -44.1492225 -19.9477024, -44.149453 -19.9476684, -44.149694 -19.9476387, -44.1499556 -19.9475436, -44.1501398 -19.9474234, -44.1502723 -19.9473206, -44.150421 -19.9471473, -44.1505043 -19.9470004, -44.1507664 -19.9462594, -44.150867 -19.9459518, -44.1509225 -19.9457843, -44.1511168 -19.945466, -44.1513601 -19.9452272, -44.1516846 -19.944999, -44.15197 -19.9448738, -44.1525994 -19.9447263, -44.1536614 -19.9444791, -44.1544071 -19.9442671, -44.1548978 -19.9441275, -44.1556247 -19.9438304, -44.1565996 -19.9434083, -44.1570351 -19.9432556, -44.1573142 -19.9432091, -44.1575332 -19.9431645, -44.157931 -19.9431484, -44.1586408 -19.9431504, -44.1593575 -19.9431457, -44.1596498 -19.9431562, -44.1600991 -19.9431475, -44.1602331 -19.9431567, -44.1607926 -19.9432449, -44.1609723 -19.9432499, -44.1623815 -19.9432765, -44.1628299 -19.9433645, -44.1632475 -19.9435839, -44.1633456 -19.9436559, -44.1636261 -19.9439375, -44.1638186 -19.9442439, -44.1642535 -19.9451781, -44.165178 -19.947156, -44.1652928 -19.9474016, -44.1653074 -19.9474329, -44.1654026 -19.947766, -44.1654774 -19.9481718, -44.1655699 -19.9490241, -44.1656196 -19.9491538, -44.1659735 -19.9499097, -44.1662485 -19.9504925, -44.1662996 -19.9506347, -44.1663574 -19.9512961, -44.1664094 -19.9519273, -44.1664144 -19.9519881, -44.1664799 -19.9526399, -44.1666965 -19.9532586, -44.1671191 -19.9544126, -44.1672019 -19.9545869, -44.1673344 -19.9547603, -44.1675958 -19.9550466, -44.1692349 -19.9567775, -44.1694607 -19.9569284, -44.1718843 -19.9574147, -44.1719167 -19.9574206, -44.1721627 -19.9574748, -44.1723207 -19.9575386, -44.1724439 -19.9575883, -44.1742798 -19.9583293, -44.1748841 -19.9585688, -44.1751118 -19.9586796, -44.1752554 -19.9587769, -44.1752644 -19.9587881, -44.1756052 -19.9592143, -44.1766415 -19.9602689, -44.1774912 -19.9612387, -44.177663 -19.961364, -44.177856 -19.9614494, -44.178034 -19.9615125, -44.1782475 -19.9615423, -44.1785115 -19.9615155, -44.1795404 -19.9610879, -44.1796393 -19.9610759, -44.1798873 -19.9610459, -44.1802404 -19.961036, -44.1804714 -19.9609634, -44.181059 -19.9605365, -44.1815113 -19.9602333, -44.1826712 -19.9594067, -44.1829715 -19.9592551, -44.1837201 -19.9590611, -44.1839277 -19.9590073, -44.1853022 -19.9586512, -44.1856812 -19.9585316, -44.1862915 -19.9584212, -44.1866215 -19.9583494, -44.1867651 -19.9583391, -44.1868852 -19.9583372, -44.1872523 -19.9583313, -44.187823 -19.9583281, -44.1884457 -19.958351, -44.1889559 -19.958437, -44.1893825 -19.9585816, -44.1897582 -19.9587828, -44.1901186 -19.9590453, -44.1912457 -19.9602029, -44.1916575 -19.9606307, -44.1921624 -19.9611588, -44.1925367 -19.9615872, -44.1931832 -19.9622566, -44.1938468 -19.9629343, -44.194089 -19.9631996, -44.1943924 -19.9634141, -44.1946006 -19.9635104, -44.1948789 -19.963599, -44.1957402 -19.9637569, -44.1964094 -19.9638505, -44.1965875 -19.9639188, -44.1967865 -19.9640801, -44.197096 -19.9643572, -44.1972765 -19.964458, -44.1974407 -19.9644824, -44.1976234 -19.9644668, -44.1977654 -19.9644282, -44.1980715 -19.96417, -44.1984541 -19.9638069, -44.1986632 -19.9636002, -44.1988132 -19.9634172, -44.1989542 -19.9632962, -44.1991349 -19.9631081)");
+ OGCGeometry result12 = point.union(lineString);
+ String text12 = result12.asText();
+ assertEquals(text12, "LINESTRING (-44.1247493 -19.9467657, -44.1247979 -19.9468385, -44.1249043 -19.946934, -44.1251096 -19.9470651, -44.1252609 -19.9471383, -44.1254992 -19.947204, -44.1257652 -19.947229, -44.1261292 -19.9471833, -44.1268946 -19.9470098, -44.1276847 -19.9468416, -44.127831 -19.9468143, -44.1282639 -19.9467366, -44.1284569 -19.9467237, -44.1287119 -19.9467261, -44.1289437 -19.9467665, -44.1291499 -19.9468221, -44.1293856 -19.9469396, -44.1298857 -19.9471497, -44.1300908 -19.9472071, -44.1302743 -19.9472331, -44.1305029 -19.9472364, -44.1306498 -19.9472275, -44.1308054 -19.947216, -44.1308553 -19.9472037, -44.1313206 -19.9471394, -44.1317889 -19.9470854, -44.1330422 -19.9468887, -44.1337465 -19.9467083, -44.1339922 -19.9466842, -44.1341506 -19.9466997, -44.1343621 -19.9467226, -44.1345134 -19.9467855, -44.1346494 -19.9468456, -44.1347295 -19.946881, -44.1347988 -19.9469299, -44.1350231 -19.9471131, -44.1355843 -19.9478307, -44.1357802 -19.9480557, -44.1366289 -19.949198, -44.1370384 -19.9497001, -44.137386 -19.9501921, -44.1374113 -19.9502263, -44.1380888 -19.9510925, -44.1381769 -19.9513526, -44.1382509 -19.9516202, -44.1383014 -19.9522136, -44.1383889 -19.9530931, -44.1384227 -19.9538784, -44.1384512 -19.9539653, -44.1384555 -19.9539807, -44.1384901 -19.9541928, -44.1385563 -19.9543859, -44.1386656 -19.9545781, -44.1387339 -19.9546889, -44.1389219 -19.9548661, -44.1391695 -19.9550384, -44.1393672 -19.9551414, -44.1397538 -19.9552208, -44.1401714 -19.9552332, -44.1405656 -19.9551143, -44.1406198 -19.9550853, -44.1407579 -19.9550224, -44.1409029 -19.9549201, -44.1410283 -19.9548257, -44.1413902 -19.9544132, -44.141835 -19.9539274, -44.142268 -19.953484, -44.1427036 -19.9531023, -44.1436229 -19.952259, -44.1437568 -19.9521565, -44.1441783 -19.9517273, -44.144644 -19.9512109, -44.1452538 -19.9505663, -44.1453541 -19.9504774, -44.1458653 -19.9500442, -44.1463563 -19.9496473, -44.1467534 -19.9492812, -44.1470553 -19.9490028, -44.1475804 -19.9485293, -44.1479838 -19.9482096, -44.1485003 -19.9478532, -44.1489451 -19.9477314, -44.1492225 -19.9477024, -44.149453 -19.9476684, -44.149694 -19.9476387, -44.1499556 -19.9475436, -44.1501398 -19.9474234, -44.1502723 -19.9473206, -44.150421 -19.9471473, -44.1505043 -19.9470004, -44.1507664 -19.9462594, -44.150867 -19.9459518, -44.1509225 -19.9457843, -44.1511168 -19.945466, -44.1513601 -19.9452272, -44.1516846 -19.944999, -44.15197 -19.9448738, -44.1525994 -19.9447263, -44.1536614 -19.9444791, -44.1544071 -19.9442671, -44.1548978 -19.9441275, -44.1556247 -19.9438304, -44.1565996 -19.9434083, -44.1570351 -19.9432556, -44.1573142 -19.9432091, -44.1575332 -19.9431645, -44.157931 -19.9431484, -44.1586408 -19.9431504, -44.1593575 -19.9431457, -44.1596498 -19.9431562, -44.1600991 -19.9431475, -44.1602331 -19.9431567, -44.1607926 -19.9432449, -44.1609723 -19.9432499, -44.16176186699087 -19.94326480383335, -44.1623815 -19.9432765, -44.1628299 -19.9433645, -44.1632475 -19.9435839, -44.1633456 -19.9436559, -44.1636261 -19.9439375, -44.1638186 -19.9442439, -44.1642535 -19.9451781, -44.165178 -19.947156, -44.1652928 -19.9474016, -44.1653074 -19.9474329, -44.1654026 -19.947766, -44.1654774 -19.9481718, -44.1655699 -19.9490241, -44.1656196 -19.9491538, -44.1659735 -19.9499097, -44.1662485 -19.9504925, -44.1662996 -19.9506347, -44.1663574 -19.9512961, -44.1664094 -19.9519273, -44.1664144 -19.9519881, -44.1664799 -19.9526399, -44.1666965 -19.9532586, -44.1671191 -19.9544126, -44.1672019 -19.9545869, -44.1673344 -19.9547603, -44.1675958 -19.9550466, -44.1692349 -19.9567775, -44.1694607 -19.9569284, -44.1718843 -19.9574147, -44.1719167 -19.9574206, -44.1721627 -19.9574748, -44.1723207 -19.9575386, -44.1724439 -19.9575883, -44.1742798 -19.9583293, -44.1748841 -19.9585688, -44.1751118 -19.9586796, -44.1752554 -19.9587769, -44.1752644 -19.9587881, -44.1756052 -19.9592143, -44.1766415 -19.9602689, -44.1774912 -19.9612387, -44.177663 -19.961364, -44.177856 -19.9614494, -44.178034 -19.9615125, -44.1782475 -19.9615423, -44.1785115 -19.9615155, -44.1795404 -19.9610879, -44.1796393 -19.9610759, -44.1798873 -19.9610459, -44.1802404 -19.961036, -44.1804714 -19.9609634, -44.181059 -19.9605365, -44.1815113 -19.9602333, -44.1826712 -19.9594067, -44.1829715 -19.9592551, -44.1837201 -19.9590611, -44.1839277 -19.9590073, -44.1853022 -19.9586512, -44.1856812 -19.9585316, -44.1862915 -19.9584212, -44.1866215 -19.9583494, -44.1867651 -19.9583391, -44.1868852 -19.9583372, -44.1872523 -19.9583313, -44.187823 -19.9583281, -44.1884457 -19.958351, -44.1889559 -19.958437, -44.1893825 -19.9585816, -44.1897582 -19.9587828, -44.1901186 -19.9590453, -44.1912457 -19.9602029, -44.1916575 -19.9606307, -44.1921624 -19.9611588, -44.1925367 -19.9615872, -44.1931832 -19.9622566, -44.1938468 -19.9629343, -44.194089 -19.9631996, -44.1943924 -19.9634141, -44.1946006 -19.9635104, -44.1948789 -19.963599, -44.1957402 -19.9637569, -44.1964094 -19.9638505, -44.1965875 -19.9639188, -44.1967865 -19.9640801, -44.197096 -19.9643572, -44.1972765 -19.964458, -44.1974407 -19.9644824, -44.1976234 -19.9644668, -44.1977654 -19.9644282, -44.1980715 -19.96417, -44.1984541 -19.9638069, -44.1986632 -19.9636002, -44.1988132 -19.9634172, -44.1989542 -19.9632962, -44.1991349 -19.9631081)");
+ }
}
diff --git a/src/test/java/com/esri/core/geometry/TestOGCCentroid.java b/src/test/java/com/esri/core/geometry/TestOGCCentroid.java
new file mode 100644
index 00000000..a64c67b5
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestOGCCentroid.java
@@ -0,0 +1,106 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.ogc.OGCGeometry;
+import com.esri.core.geometry.ogc.OGCPoint;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestOGCCentroid {
+ @Test
+ public void testPoint() {
+ assertCentroid("POINT (1 2)", new Point(1, 2));
+ assertEmptyCentroid("POINT EMPTY");
+ }
+
+ @Test
+ public void testLineString() {
+ assertCentroid("LINESTRING (1 1, 2 2, 3 3)", new Point(2, 2));
+ //closed path
+ assertCentroid("LINESTRING (0 0, 1 0, 1 1, 0 1, 0 0)", new Point(0.5, 0.5));
+ //all points coincide
+ assertCentroid("LINESTRING (0 0, 0 0, 0 0, 0 0, 0 0)", new Point(0.0, 0.0));
+ assertEmptyCentroid("LINESTRING EMPTY");
+ }
+
+ @Test
+ public void testPolygon() {
+ assertCentroid("POLYGON ((1 1, 1 4, 4 4, 4 1))'", new Point(2.5, 2.5));
+ assertCentroid("POLYGON ((1 1, 5 1, 3 4))", new Point(3, 2));
+ assertCentroid("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1))",
+ new Point(2.5416666666666665, 2.5416666666666665));
+ assertEmptyCentroid("POLYGON EMPTY");
+ }
+
+ @Test
+ public void testMultiPoint() {
+ assertCentroid("MULTIPOINT (1 2, 2 4, 3 6, 4 8)", new Point(2.5, 5));
+ assertEmptyCentroid("MULTIPOINT EMPTY");
+ }
+
+ @Test
+ public void testMultiLineString() {
+ assertCentroid("MULTILINESTRING ((1 1, 5 1), (2 4, 4 4))')))", new Point(3, 2));
+ assertCentroid("MULTILINESTRING ((1 1, 5 1), (2 4, 3 3, 4 4))')))", new Point(3, 2.0355339059327378));
+ assertCentroid("MULTILINESTRING ((0 0, 0 0, 0 0), (1 1, 1 1, 1 1, 1 1))", new Point(0.571428571428571429, 0.571428571428571429));
+ assertEmptyCentroid("MULTILINESTRING EMPTY");
+ }
+
+ @Test
+ public void testMultiPolygon() {
+ assertCentroid("MULTIPOLYGON (((0 0, 1 0, 1 1, 0 1, 0 0)), ((2 2, 3 2, 3 3, 2 3, 2 2)))", new Point(1.5, 1.5));
+ assertCentroid("MULTIPOLYGON (((2 2, 3 2, 3 3, 2 3, 2 2)), ((4 4, 5 4, 5 5, 4 5, 4 4)))", new Point(3.5, 3.5));
+ assertCentroid("MULTIPOLYGON (((1 1, 1 3, 3 3, 3 1)), ((2 4, 2 6, 6 6, 6 4)))",
+ new Point(3.3333333333333335, 4));
+
+ //hole is same as exterior - compute as polyline
+ assertCentroid("MULTIPOLYGON (((0 0, 1 0, 1 1, 0 1, 0 0), (0 0, 0 1, 1 1, 1 0, 0 0)))", new Point(0.5, 0.5));
+
+ //polygon is only vertices - compute as multipoint. Note that the closing vertex of the ring is not counted
+ assertCentroid("MULTIPOLYGON (((0 0, 0 0, 0 0), (1 1, 1 1, 1 1, 1 1)))", new Point(0.6, 0.6));
+
+ // test cases from https://github.com/Esri/geometry-api-java/issues/225
+ assertCentroid(
+ "MULTIPOLYGON (((153.492818 -28.13729, 153.492821 -28.137291, 153.492816 -28.137289, 153.492818 -28.13729)))",
+ new Point(153.49281833333333, -28.13729));
+ assertCentroid(
+ "MULTIPOLYGON (((153.112475 -28.360526, 153.1124759 -28.360527, 153.1124759 -28.360526, 153.112475 -28.360526)))",
+ new Point(153.1124756, -28.360526333333333));
+ assertEmptyCentroid("MULTIPOLYGON EMPTY");
+ }
+
+ private static void assertCentroid(String wkt, Point expectedCentroid) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry centroid = geometry.centroid();
+ Assert.assertEquals(((OGCPoint)centroid).X(), expectedCentroid.getX(), 1e-13);
+ Assert.assertEquals(((OGCPoint)centroid).Y(), expectedCentroid.getY(), 1e-13);
+ }
+
+ private static void assertEmptyCentroid(String wkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry centroid = geometry.centroid();
+ Assert.assertEquals(centroid, new OGCPoint(new Point(), geometry.getEsriSpatialReference()));
+ }
+}
diff --git a/src/test/java/com/esri/core/geometry/TestOGCContains.java b/src/test/java/com/esri/core/geometry/TestOGCContains.java
new file mode 100644
index 00000000..04a328bf
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestOGCContains.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed 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 com.esri.core.geometry;
+
+import com.esri.core.geometry.ogc.OGCGeometry;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TestOGCContains {
+ @Test
+ public void testPoint() {
+ // point
+ assertContains("POINT (1 2)", "POINT (1 2)");
+ assertContains("POINT (1 2)", "GEOMETRYCOLLECTION (POINT (1 2))");
+ assertNotContains("POINT (1 2)", "POINT EMPTY");
+ assertNotContains("POINT (1 2)", "POINT (3 4)");
+
+ // multi-point
+ assertContains("MULTIPOINT (1 2, 3 4)", "MULTIPOINT (1 2, 3 4)");
+ assertContains("MULTIPOINT (1 2, 3 4)", "MULTIPOINT (1 2)");
+ assertContains("MULTIPOINT (1 2, 3 4)", "POINT (3 4)");
+ assertContains("MULTIPOINT (1 2, 3 4)", "GEOMETRYCOLLECTION (MULTIPOINT (1 2), POINT (3 4))");
+ assertContains("MULTIPOINT (1 2, 3 4)", "GEOMETRYCOLLECTION (POINT (1 2))");
+ assertNotContains("MULTIPOINT (1 2, 3 4)", "MULTIPOINT EMPTY");
+ }
+
+ @Test
+ public void testLineString() {
+ // TODO Add more tests
+ assertContains("LINESTRING (0 1, 5 1)", "POINT (2 1)");
+ }
+
+ @Test
+ public void testPolygon() {
+ // TODO Fill in
+ }
+
+ @Test
+ public void testGeometryCollection() {
+ // TODO Add more tests
+ assertContains("GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (0 1, 5 1))",
+ "GEOMETRYCOLLECTION (MULTIPOINT (0 0, 2 1))");
+ }
+
+ @Test
+ public void testAcceleratedPiP() {
+ String wkt = "MULTIPOLYGON (((-109.642707 30.5236901, -109.607932 30.5367411, -109.5820257 30.574184, -109.5728286 30.5874766, -109.568679 30.5934741, -109.5538097 30.5918356, -109.553714 30.5918251, -109.553289 30.596034, -109.550951 30.6191889, -109.5474935 30.6221179, -109.541059 30.6275689, -109.5373751 30.6326491, -109.522538 30.6531099, -109.514671 30.6611981, -109.456764 30.6548095, -109.4556456 30.6546861, -109.4536755 30.6544688, -109.4526481 30.6543554, -109.446824 30.6537129, -109.437751 30.6702901, -109.433968 30.6709781, -109.43338 30.6774591, -109.416243 30.7164651, -109.401643 30.7230741, -109.377583 30.7145241, -109.3487939 30.7073896, -109.348594 30.7073401, -109.3483718 30.7073797, -109.3477608 30.7074887, -109.3461903 30.7078834, -109.3451022 30.7081569, -109.3431732 30.7086416, -109.3423301 30.708844, -109.3419714 30.7089301, -109.3416347 30.709011, -109.3325693 30.7111874, -109.3323814 30.7112325, -109.332233 30.7112681, -109.332191 30.7112686, -109.3247809 30.7113581, -109.322215 30.7159391, -109.327776 30.7234381, -109.350134 30.7646001, -109.364505 30.8382481, -109.410211 30.8749199, -109.400048 30.8733419, -109.3847799 30.9652412, -109.3841625 30.9689575, -109.375268 31.0224939, -109.390544 31.0227899, -109.399749 31.0363341, -109.395787 31.0468411, -109.388174 31.0810249, -109.3912446 31.0891966, -109.3913452 31.0894644, -109.392735 31.0931629, -109.4000839 31.0979214, -109.402803 31.0996821, -109.4110458 31.1034586, -109.419153 31.1071729, -109.449782 31.1279489, -109.469654 31.1159979, -109.4734874 31.1131178, -109.473753 31.1129183, -109.4739754 31.1127512, -109.491296 31.0997381, -109.507789 31.0721811, -109.512776 31.0537519, -109.5271478 31.0606861, -109.5313703 31.0627234, -109.540698 31.0672239, -109.5805468 31.0674089, -109.5807399 31.0674209, -109.595423 31.0674779, -109.60347 31.0690241, -109.6048011 31.068808, -109.6050803 31.0687627, -109.6192237 31.0664664, -109.635432 31.0638349, -109.6520068 31.0955326, -109.6522294 31.0959584, -109.652373 31.0962329, -109.657709 31.0959719, -109.718258 31.0930099, -109.821036 31.0915909, -109.8183088 31.0793374, -109.8165128 31.0712679, -109.8140062 31.0600052, -109.8138512 31.0593089, -109.812707 31.0541679, -109.8188146 31.0531909, -109.8215447 31.0527542, -109.8436765 31.0492138, -109.8514316 31.0479733, -109.8620535 31.0462742, -109.8655958 31.0457076, -109.868388 31.0452609, -109.8795483 31.0359656, -109.909274 31.0112075, -109.9210382 31.0014092, -109.9216329 31.0009139, -109.920594 30.994183, -109.9195356 30.9873254, -109.9192113 30.9852243, -109.9186281 30.9814453, -109.917814 30.9761709, -109.933894 30.9748879, -109.94094 30.9768059, -109.944854 30.9719821, -109.950803 30.9702809, -109.954025 30.9652409, -109.9584129 30.9636033, -109.958471 30.9635809, -109.9590542 30.9644372, -109.959896 30.9656733, -109.9604184 30.9664405, -109.9606288 30.9667494, -109.9608462 30.9670686, -109.961225 30.9676249, -109.9611615 30.9702903, -109.9611179 30.9721175, -109.9610885 30.9733488, -109.9610882 30.9733604, -109.9610624 30.9744451, -109.961017 30.9763469, -109.962609 30.9786559, -109.9634437 30.9783167, -110.00172 30.9627641, -110.0021152 30.9627564, -110.0224353 30.9623622, -110.0365868 30.9620877, -110.037493 30.9620701, -110.0374055 30.961663, -110.033653 30.9442059, -110.0215506 30.9492932, -110.0180392 30.9507693, -110.011203 30.9536429, -110.0062891 30.9102124, -110.0058721 30.9065268, -110.004869 30.8976609, -109.996392 30.8957129, -109.985038 30.8870439, -109.969416 30.9006011, -109.967905 30.8687239, -109.903498 30.8447749, -109.882925 30.8458289, -109.865184 30.8206519, -109.86465 30.777698, -109.864515 30.7668429, -109.837007 30.7461781, -109.83453 30.7164469, -109.839017 30.7089009, -109.813394 30.6906529, -109.808694 30.6595701, -109.795334 30.6630041, -109.7943042 30.6427223, -109.7940456 30.6376287, -109.7940391 30.637501, -109.793823 30.6332449, -109.833511 30.6274289, -109.830299 30.6252799, -109.844198 30.6254801, -109.852442 30.6056949, -109.832973 30.6021201, -109.8050409 30.591211, -109.773847 30.5790279, -109.772859 30.5521999, -109.754427 30.5393969, -109.743293 30.5443401, -109.6966136 30.5417334, -109.6648181 30.5399578, -109.6560456 30.5394679, -109.6528439 30.5392912, -109.6504039 30.5391565, -109.6473602 30.5389885, -109.646906 30.5389634, -109.6414545 30.5386625, -109.639708 30.5385661, -109.6397729 30.5382443, -109.642707 30.5236901)))";
+ String pointWkt = "POINT (-109.65 31.091666666673)";
+
+ OGCGeometry polygon = OGCGeometry.fromText(wkt);
+ OGCGeometry point = OGCGeometry.fromText(pointWkt);
+ assertTrue(polygon.contains(point));
+
+ OperatorContains.local()
+ .accelerateGeometry(polygon.getEsriGeometry(), null, Geometry.GeometryAccelerationDegree.enumMild);
+ assertTrue(polygon.contains(point));;
+ }
+
+ private void assertContains(String wkt, String otherWkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+
+ assertTrue(geometry.contains(otherGeometry));
+ assertTrue(otherGeometry.within(geometry));
+ assertFalse(geometry.disjoint(otherGeometry));
+ }
+
+ private void assertNotContains(String wkt, String otherWkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+ assertFalse(geometry.contains(otherGeometry));
+ assertFalse(otherGeometry.within(geometry));
+ }
+}
+
diff --git a/src/test/java/com/esri/core/geometry/TestOGCDisjoint.java b/src/test/java/com/esri/core/geometry/TestOGCDisjoint.java
new file mode 100644
index 00000000..45090e83
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestOGCDisjoint.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed 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 com.esri.core.geometry;
+
+import com.esri.core.geometry.ogc.OGCGeometry;
+import org.junit.Test;
+
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TestOGCDisjoint
+{
+ @Test
+ public void testPoint()
+ {
+ // point
+ assertDisjoint("POINT (1 2)", "POINT (3 4)");
+ assertDisjoint("POINT (1 2)", "POINT EMPTY");
+ assertNotDisjoint("POINT (1 2)", "POINT (1 2)", "POINT (1 2)");
+
+ // multi-point
+ assertDisjoint("POINT (1 2)", "MULTIPOINT (3 4, 5 6)");
+ assertDisjoint("POINT (1 2)", "MULTIPOINT EMPTY");
+ assertNotDisjoint("POINT (1 2)", "MULTIPOINT (1 2, 3 4, 5 6)", "POINT (1 2)");
+ assertNotDisjoint("POINT (1 2)", "MULTIPOINT (1 2)", "POINT (1 2)");
+ }
+
+ @Test
+ public void testLinestring()
+ {
+ // TODO Fill in
+ }
+
+ @Test
+ public void testPolygon()
+ {
+ // TODO Fill in
+ }
+
+ @Test
+ public void testGeometryCollection()
+ {
+ assertDisjoint("GEOMETRYCOLLECTION (POINT (1 2))", "POINT (3 4)");
+ // GeometryException: internal error
+ assertDisjoint("GEOMETRYCOLLECTION (POINT (1 2))", "POINT EMPTY");
+ assertNotDisjoint("GEOMETRYCOLLECTION (POINT (1 2))", "POINT (1 2)", "POINT (1 2)");
+
+ assertDisjoint("GEOMETRYCOLLECTION (POINT (1 2), MULTIPOINT (3 4, 5 6))", "POINT (0 0)");
+ assertNotDisjoint("GEOMETRYCOLLECTION (POINT (1 2), MULTIPOINT (3 4, 5 6))", "POINT (3 4)", "POINT (3 4)");
+
+ String wkt = "GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (0 0, 5 0), POLYGON ((2 2, 3 2, 3 3, 2 2)))";
+ assertDisjoint(wkt, gc("POINT (0 2)"));
+
+ assertNotDisjoint(wkt, gc("POINT (1 2)"), "POINT (1 2)");
+ // point within the line
+ assertNotDisjoint(wkt, gc("POINT (0 0)"), "POINT (0 0)");
+ assertNotDisjoint(wkt, gc("POINT (1 0)"), "POINT (1 0)");
+ // point within the polygon
+ assertNotDisjoint(wkt, gc("POINT (2 2)"), "POINT (2 2)");
+ assertNotDisjoint(wkt, gc("POINT (2.5 2)"), "POINT (2.5 2)");
+ assertNotDisjoint(wkt, gc("POINT (2.5 2.1)"), "POINT (2.5 2.1)");
+
+ assertDisjoint(wkt, gc("LINESTRING (0 2, 1 3)"));
+
+ // line intersects the point
+ assertNotDisjoint(wkt, gc("LINESTRING (0 1, 2 3)"), "POINT (1 2)");
+ // line intersects the line
+ assertNotDisjoint(wkt, gc("LINESTRING (0 0, 1 0)"), "LINESTRING (0 0, 1 0)");
+ assertNotDisjoint(wkt, gc("LINESTRING (5 -1, 5 1)"), "POINT (5 0)");
+ // line intersects the polygon
+ assertNotDisjoint(wkt, gc("LINESTRING (0 0, 5 5)"), gc("POINT (0 0), LINESTRING (2 2, 3 3)"));
+ assertNotDisjoint(wkt, gc("LINESTRING (0 2.5, 2.6 2.5)"), "LINESTRING (2.5 2.5, 2.6 2.5)");
+
+ assertDisjoint(wkt, gc("POLYGON ((5 5, 6 5, 6 6, 5 5))"));
+ assertDisjoint(wkt, gc("POLYGON ((-1 -1, 10 -1, 10 10, -1 10, -1 -1), (-0.1 -0.1, 5.1 -0.1, 5.1 5.1, -0.1 5.1, -0.1 -0.1))"));
+
+ assertNotDisjoint(wkt, gc("POLYGON ((-1 -1, 10 -1, 10 10, -1 10, -1 -1))"), gc("POINT (1 2), LINESTRING (0 0, 5 0), POLYGON ((2 2, 3 2, 3 3, 2 2))"));
+ assertNotDisjoint(wkt, gc("POLYGON ((2 -1, 4 -1, 4 1, 2 1, 2 -1))"), "LINESTRING (2 0, 4 0)");
+ assertNotDisjoint(wkt, gc("POLYGON ((0 1, 1.5 1, 1.5 2.5, 0 2.5, 0 1))"), "POINT (1 2)");
+ assertNotDisjoint(wkt, gc("POLYGON ((5 0, 6 0, 6 5, 5 0))"), "POINT (5 0)");
+ }
+
+ private String gc(String wkts)
+ {
+ return format("GEOMETRYCOLLECTION (%s)", wkts);
+ }
+
+ private void assertDisjoint(String wkt, String otherWkt)
+ {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+ assertTrue(geometry.disjoint(otherGeometry));
+ assertFalse(geometry.intersects(otherGeometry));
+ assertTrue(geometry.intersection(otherGeometry).isEmpty());
+
+ assertTrue(otherGeometry.disjoint(geometry));
+ assertFalse(otherGeometry.intersects(geometry));
+ assertTrue(otherGeometry.intersection(geometry).isEmpty());
+ }
+
+ private void assertNotDisjoint(String wkt, String otherWkt, String intersectionWkt)
+ {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+ assertFalse(geometry.disjoint(otherGeometry));
+ assertTrue(geometry.intersects(otherGeometry));
+ assertEquals(intersectionWkt, geometry.intersection(otherGeometry).asText());
+
+ assertFalse(otherGeometry.disjoint(geometry));
+ assertTrue(otherGeometry.intersects(geometry));
+ assertEquals(intersectionWkt, otherGeometry.intersection(geometry).asText());
+ }
+}
diff --git a/src/test/java/com/esri/core/geometry/TestOGCDistance.java b/src/test/java/com/esri/core/geometry/TestOGCDistance.java
new file mode 100644
index 00000000..dea491f9
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestOGCDistance.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed 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 com.esri.core.geometry;
+
+import org.junit.Test;
+
+import static com.esri.core.geometry.ogc.OGCGeometry.fromText;
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+
+public class TestOGCDistance
+{
+ @Test
+ public void testPoint()
+ {
+ assertDistance("POINT (1 2)", "POINT (2 2)", 1);
+ assertDistance("POINT (1 2)", "POINT (1 2)", 0);
+ assertNanDistance("POINT (1 2)", "POINT EMPTY");
+
+ assertDistance(gc("POINT (1 2)"), "POINT (2 2)", 1);
+ assertDistance(gc("POINT (1 2)"), "POINT (1 2)", 0);
+ assertNanDistance(gc("POINT (1 2)"), "POINT EMPTY");
+ assertDistance(gc("POINT (1 2)"), gc("POINT (2 2)"), 1);
+
+ assertDistance("MULTIPOINT (1 0, 2 0, 3 0)", "POINT (2 1)", 1);
+ assertDistance(gc("MULTIPOINT (1 0, 2 0, 3 0)"), "POINT (2 1)", 1);
+ assertDistance(gc("POINT (1 0), POINT (2 0), POINT (3 0))"), "POINT (2 1)", 1);
+
+ assertDistance(gc("POINT (1 0), POINT EMPTY"), "POINT (2 0)", 1);
+ }
+
+ private void assertDistance(String wkt, String otherWkt, double distance)
+ {
+ assertEquals(distance, fromText(wkt).distance(fromText(otherWkt)), 0.000001);
+ assertEquals(distance, fromText(otherWkt).distance(fromText(wkt)), 0.000001);
+ }
+
+ private void assertNanDistance(String wkt, String otherWkt)
+ {
+ assertEquals(Double.NaN, fromText(wkt).distance(fromText(otherWkt)), 0.000001);
+ assertEquals(Double.NaN, fromText(otherWkt).distance(fromText(wkt)), 0.000001);
+ }
+
+ private String gc(String wkts)
+ {
+ return format("GEOMETRYCOLLECTION (%s)", wkts);
+ }
+}
diff --git a/src/test/java/com/esri/core/geometry/TestOGCGeometryCollection.java b/src/test/java/com/esri/core/geometry/TestOGCGeometryCollection.java
new file mode 100644
index 00000000..53007166
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestOGCGeometryCollection.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed 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 com.esri.core.geometry;
+
+import com.esri.core.geometry.ogc.OGCGeometry;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestOGCGeometryCollection {
+ @Test
+ public void testUnionPoint() {
+ // point - point
+ assertUnion("POINT (1 2)", "POINT (1 2)", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "POINT EMPTY", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "POINT (3 4)", "MULTIPOINT ((1 2), (3 4))");
+
+ // point - multi-point
+ assertUnion("POINT (1 2)", "MULTIPOINT (1 2)", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "MULTIPOINT EMPTY", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "MULTIPOINT (3 4)", "MULTIPOINT ((1 2), (3 4))");
+ assertUnion("POINT (1 2)", "MULTIPOINT (1 2, 3 4)", "MULTIPOINT ((1 2), (3 4))");
+ assertUnion("POINT (1 2)", "MULTIPOINT (3 4, 5 6)", "MULTIPOINT ((1 2), (3 4), (5 6))");
+
+ // point - linestring
+ assertUnion("POINT (1 2)", "LINESTRING (3 4, 5 6)", "GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6))");
+ assertUnion("POINT (1 2)", "LINESTRING EMPTY", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "LINESTRING (1 2, 3 4)", "LINESTRING (1 2, 3 4)");
+ assertUnion("POINT (1 2)", "LINESTRING (1 1, 1 3, 3 4)", "LINESTRING (1 1, 1 2, 1 3, 3 4)");
+
+ // point - multi-linestring
+ assertUnion("POINT (1 2)", "MULTILINESTRING ((3 4, 5 6))",
+ "GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6))");
+ assertUnion("POINT (1 2)", "MULTILINESTRING EMPTY", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "MULTILINESTRING ((3 4, 5 6), (7 8, 9 10, 11 12))",
+ "GEOMETRYCOLLECTION (POINT (1 2), MULTILINESTRING ((3 4, 5 6), (7 8, 9 10, 11 12)))");
+ assertUnion("POINT (1 2)", "MULTILINESTRING ((1 2, 3 4))", "LINESTRING (1 2, 3 4)");
+ assertUnion("POINT (1 2)", "MULTILINESTRING ((1 1, 1 3, 3 4), (7 8, 9 10, 11 12))",
+ "MULTILINESTRING ((1 1, 1 2, 1 3, 3 4), (7 8, 9 10, 11 12))");
+
+ // point - polygon
+ assertUnion("POINT (1 2)", "POLYGON ((0 0, 1 0, 1 1, 0 0))",
+ "GEOMETRYCOLLECTION (POINT (1 2), POLYGON ((0 0, 1 0, 1 1, 0 0)))");
+ assertUnion("POINT (1 2)", "POLYGON EMPTY", "POINT (1 2)");
+ // point inside polygon
+ assertUnion("POINT (1 2)", "POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0))", "POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0))");
+ // point inside polygon with a hole
+ assertUnion("POINT (1 2)", "POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0), (2 2, 2 2.5, 2.5 2.5, 2.5 2, 2 2))",
+ "POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0), (2 2, 2 2.5, 2.5 2.5, 2.5 2, 2 2))");
+ // point inside polygon's hole
+ assertUnion("POINT (1 2)", "POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0), (0.5 1, 0.5 2.5, 2.5 2.5, 2.5 1, 0.5 1))",
+ "GEOMETRYCOLLECTION (POINT (1 2), POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0), (0.5 1, 0.5 2.5, 2.5 2.5, 2.5 1, 0.5 1)))");
+ // point is a vertex of the polygon
+ assertUnion("POINT (1 2)", "POLYGON ((1 2, 2 2, 2 3, 1 3, 1 2))", "POLYGON ((1 2, 2 2, 2 3, 1 3, 1 2))");
+ // point on the boundary of the polybon
+ assertUnion("POINT (1 2)", "POLYGON ((1 1, 2 1, 2 3, 1 3, 1 1))", "POLYGON ((1 1, 2 1, 2 3, 1 3, 1 2, 1 1))");
+
+ // point - multi-polygon
+ assertUnion("POINT (1 2)", "MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))",
+ "GEOMETRYCOLLECTION (POINT (1 2), POLYGON ((0 0, 1 0, 1 1, 0 0)))");
+ assertUnion("POINT (1 2)", "MULTIPOLYGON EMPTY", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "MULTIPOLYGON (((0 0, 3 0, 3 3, 0 3, 0 0)))", "POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0))");
+ assertUnion("POINT (1 2)", "MULTIPOLYGON (((0 0, 3 0, 3 3, 0 3, 0 0)), ((4 4, 5 4, 5 5, 4 4)))",
+ "MULTIPOLYGON (((0 0, 3 0, 3 3, 0 3, 0 0)), ((4 4, 5 4, 5 5, 4 4)))");
+ assertUnion("POINT (1 2)",
+ "MULTIPOLYGON (((0 0, 3 0, 3 3, 0 3, 0 0), (0.5 1, 0.5 2.5, 2.5 2.5, 2.5 1, 0.5 1)))",
+ "GEOMETRYCOLLECTION (POINT (1 2), POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0), (0.5 1, 0.5 2.5, 2.5 2.5, 2.5 1, 0.5 1)))");
+ assertUnion("POINT (1 2)",
+ "MULTIPOLYGON (((0 0, 3 0, 3 3, 0 3, 0 0), (0.5 1, 0.5 2.5, 2.5 2.5, 2.5 1, 0.5 1)), ((4 4, 5 4, 5 5, 4 4)))",
+ "GEOMETRYCOLLECTION (POINT (1 2), MULTIPOLYGON (((0 0, 3 0, 3 3, 0 3, 0 0), (0.5 1, 0.5 2.5, 2.5 2.5, 2.5 1, 0.5 1)), ((4 4, 5 4, 5 5, 4 4))))");
+
+ // point - geometry collection
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION (POINT (1 2))", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION EMPTY", "POINT (1 2)");
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION (POINT (1 2), POINT (2 3))", "MULTIPOINT ((1 2), (2 3))");
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION (MULTIPOINT (1 2, 2 3))", "MULTIPOINT ((1 2), (2 3))");
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION (LINESTRING (1 2, 3 4))", "LINESTRING (1 2, 3 4)");
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (1 2, 3 4))",
+ "GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (1 2, 3 4))");
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION (POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)))",
+ "POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0))");
+ assertUnion("POINT (1 2)", "GEOMETRYCOLLECTION (POINT (5 5), POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)))",
+ "GEOMETRYCOLLECTION (POINT (5 5), POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)))");
+ }
+
+ @Test
+ public void testUnionLinestring() {
+ // linestring - linestring
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING (1 2, 3 4)", "LINESTRING (1 2, 3 4)");
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING EMPTY", "LINESTRING (1 2, 3 4)");
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING (3 4, 1 2)", "LINESTRING (1 2, 3 4)");
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING (3 4, 5 6)", "LINESTRING (1 2, 3 4, 5 6)");
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING (5 6, 7 8)", "MULTILINESTRING ((1 2, 3 4), (5 6, 7 8))");
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING (2 1, 2 5)",
+ "MULTILINESTRING ((2 1, 2 3), (1 2, 2 3), (2 3, 3 4), (2 3, 2 5))");
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING (1 2, 2 3, 4 3)",
+ "MULTILINESTRING ((1 2, 2 3), (2 3, 4 3), (2 3, 3 4))");
+ assertUnion("LINESTRING (1 2, 3 4)", "LINESTRING (2 3, 2.1 3.1)",
+ "LINESTRING (1 2, 2 3, 2.0999999999999996 3.0999999999999996, 3 4)");
+
+ // linestring - polygon
+ assertUnion("LINESTRING (1 2, 3 4)", "POLYGON ((5 5, 6 5, 6 6, 5 5))",
+ "GEOMETRYCOLLECTION (LINESTRING (1 2, 3 4), POLYGON ((5 5, 6 5, 6 6, 5 5)))");
+ assertUnion("LINESTRING (1 2, 3 4)", "POLYGON EMPTY", "LINESTRING (1 2, 3 4)");
+ // linestring inside polygon
+ assertUnion("LINESTRING (1 2, 3 4)", "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))",
+ "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))");
+ assertUnion("LINESTRING (0 0, 5 0)", "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))",
+ "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))");
+ // linestring crosses polygon's vertex
+ assertUnion("LINESTRING (0 0, 6 6)", "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))",
+ "GEOMETRYCOLLECTION (LINESTRING (5 5, 6 6), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))");
+ assertUnion("LINESTRING (4 6, 6 4)", "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))",
+ "GEOMETRYCOLLECTION (LINESTRING (4 6, 5 5, 6 4), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))");
+ // linestring crosses polygon's boundary
+ assertUnion("LINESTRING (1 1, 1 6)", "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))",
+ "GEOMETRYCOLLECTION (LINESTRING (1 5, 1 6), POLYGON ((0 0, 5 0, 5 5, 1 5, 0 5, 0 0)))");
+
+ // linestring - geometry collection
+ assertUnion("LINESTRING (1 2, 3 4)", "GEOMETRYCOLLECTION (LINESTRING (1 2, 3 4))", "LINESTRING (1 2, 3 4)");
+ assertUnion("LINESTRING (1 2, 3 4)", "GEOMETRYCOLLECTION EMPTY", "LINESTRING (1 2, 3 4)");
+ assertUnion("LINESTRING (1 2, 3 4)", "GEOMETRYCOLLECTION (LINESTRING (3 4, 5 6))",
+ "LINESTRING (1 2, 3 4, 5 6)");
+ assertUnion("LINESTRING (1 2, 3 4)", "GEOMETRYCOLLECTION (LINESTRING (3 4, 5 6), LINESTRING (7 8, 9 10))",
+ "MULTILINESTRING ((1 2, 3 4, 5 6), (7 8, 9 10))");
+ assertUnion("LINESTRING (1 2, 3 4)", "GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6))",
+ "LINESTRING (1 2, 3 4, 5 6)");
+ assertUnion("LINESTRING (1 2, 3 4)",
+ "GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6), POLYGON ((3 0, 4 0, 4 1, 3 0)))",
+ "GEOMETRYCOLLECTION (LINESTRING (1 2, 3 4, 5 6), POLYGON ((3 0, 4 0, 4 1, 3 0)))");
+ }
+
+ @Test
+ public void testUnionPolygon() {
+ // polygon - polygon
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON ((0 0, 1 0, 1 1, 0 0))",
+ "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON EMPTY", "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ // one polygon contains the other
+ assertUnion("POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))", "POLYGON ((1 1, 2 1, 2 2, 1 1))",
+ "POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))");
+ // The following test fails because vertex order in the union geometry depends
+ // on the order of union inputs
+ // assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON ((0 0, 0.5 0, 0.5 0.5,
+ // 0 0))", "POLYGON ((0 0, 0.5 0, 1 0, 1 1, 0.49999999999999994
+ // 0.49999999999999994, 0 0))");
+ // polygons intersect
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON ((0 0.5, 2 0.5, 2 2, 0 2, 0 0.5))",
+ "POLYGON ((0 0, 1 0, 1 0.5, 2 0.5, 2 2, 0 2, 0 0.5, 0.5 0.5, 0 0))");
+ // disjoint polygons
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON ((3 3, 5 3, 5 5, 3 3))",
+ "MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((3 3, 5 3, 5 5, 3 3)))");
+
+ // polygon - multi-polygon
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))",
+ "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "MULTIPOLYGON EMPTY", "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "MULTIPOLYGON (((0 0.5, 2 0.5, 2 2, 0 2, 0 0.5)))",
+ "POLYGON ((0 0, 1 0, 1 0.5, 2 0.5, 2 2, 0 2, 0 0.5, 0.5 0.5, 0 0))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "MULTIPOLYGON (((3 3, 5 3, 5 5, 3 3)))",
+ "MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((3 3, 5 3, 5 5, 3 3)))");
+
+ // polygon - geometry collection
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "GEOMETRYCOLLECTION (POLYGON ((0 0, 1 0, 1 1, 0 0)))",
+ "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "GEOMETRYCOLLECTION EMPTY", "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))", "GEOMETRYCOLLECTION (POLYGON ((3 3, 5 3, 5 5, 3 3)))",
+ "MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((3 3, 5 3, 5 5, 3 3)))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))",
+ "GEOMETRYCOLLECTION (POINT (0 0), POLYGON ((3 3, 5 3, 5 5, 3 3)))",
+ "MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((3 3, 5 3, 5 5, 3 3)))");
+ assertUnion("POLYGON ((0 0, 1 0, 1 1, 0 0))",
+ "GEOMETRYCOLLECTION (POINT (10 10), POLYGON ((3 3, 5 3, 5 5, 3 3)))",
+ "GEOMETRYCOLLECTION (POINT (10 10), MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((3 3, 5 3, 5 5, 3 3))))");
+ }
+
+ private void assertUnion(String wkt, String otherWkt, String expectedWkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+ Assert.assertEquals(expectedWkt, geometry.union(otherGeometry).asText());
+ Assert.assertEquals(expectedWkt, otherGeometry.union(geometry).asText());
+ }
+
+ @Test
+ public void testGeometryCollectionOverlappingContains() {
+ assertContains("GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (0 1, 5 1))",
+ "GEOMETRYCOLLECTION (MULTIPOINT (0 0, 2 1))");
+ }
+
+ private void assertContains(String wkt, String otherWkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+ Assert.assertTrue(geometry.contains(otherGeometry));
+ Assert.assertTrue(otherGeometry.within(geometry));
+ }
+
+ @Test
+ public void testGeometryCollectionDisjoint() {
+ assertDisjoint("GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (0 1, 5 1))",
+ "GEOMETRYCOLLECTION (MULTIPOINT (10 0, 21 1), LINESTRING (30 0, 31 1), POLYGON ((40 0, 41 1, 40 1, 40 0)))");
+ }
+
+ private void assertDisjoint(String wkt, String otherWkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+ Assert.assertTrue(geometry.disjoint(otherGeometry));
+ Assert.assertTrue(otherGeometry.disjoint(geometry));
+ }
+
+ @Test
+ public void testGeometryCollectionIntersect() {
+ assertIntersection("GEOMETRYCOLLECTION (POINT (1 2))", "POINT EMPTY", "GEOMETRYCOLLECTION EMPTY");
+ assertIntersection("GEOMETRYCOLLECTION (POINT (1 2), MULTIPOINT (3 4, 5 6))", "POINT (3 4)",
+ "POINT (3 4)");
+ assertIntersection("GEOMETRYCOLLECTION (POINT (1 2), MULTIPOINT (3 4, 5 6))", "POINT (30 40)",
+ "GEOMETRYCOLLECTION EMPTY");
+ assertIntersection("POINT (30 40)", "GEOMETRYCOLLECTION (POINT (1 2), MULTIPOINT (3 4, 5 6))",
+ "GEOMETRYCOLLECTION EMPTY");
+ }
+
+ private void assertIntersection(String wkt, String otherWkt, String expectedWkt) {
+ OGCGeometry geometry = OGCGeometry.fromText(wkt);
+ OGCGeometry otherGeometry = OGCGeometry.fromText(otherWkt);
+ OGCGeometry result = geometry.intersection(otherGeometry);
+ Assert.assertEquals(expectedWkt, result.asText());
+ }
+}
diff --git a/src/test/java/com/esri/core/geometry/TestOGCGeometryCollectionFlatten.java b/src/test/java/com/esri/core/geometry/TestOGCGeometryCollectionFlatten.java
new file mode 100644
index 00000000..8a98d5d1
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestOGCGeometryCollectionFlatten.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed 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 com.esri.core.geometry;
+
+import com.esri.core.geometry.ogc.OGCConcreteGeometryCollection;
+import org.junit.Test;
+
+import static com.esri.core.geometry.ogc.OGCGeometry.fromText;
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestOGCGeometryCollectionFlatten
+{
+ @Test
+ public void test()
+ {
+ assertFlatten("GEOMETRYCOLLECTION EMPTY", "GEOMETRYCOLLECTION EMPTY");
+ assertFlatten(gc("POINT (1 2)"), gc("MULTIPOINT ((1 2))"));
+ assertFlatten(gc("POINT (1 2), POINT EMPTY"), gc("MULTIPOINT ((1 2))"));
+ assertFlatten(gc("POINT (1 2), MULTIPOINT (3 4, 5 6)"), gc("MULTIPOINT ((1 2), (3 4), (5 6))"));
+ assertFlatten(gc("POINT (1 2), POINT (3 4), " + gc("POINT (5 6)")), gc("MULTIPOINT ((1 2), (3 4), (5 6))"));
+ }
+
+ private void assertFlatten(String wkt, String flattenedWkt)
+ {
+ OGCConcreteGeometryCollection collection = (OGCConcreteGeometryCollection) fromText(wkt);
+ assertEquals(flattenedWkt, collection.flatten().asText());
+ assertTrue(collection.flatten().isFlattened());
+ assertEquals(flattenedWkt, collection.flatten().flatten().asText());
+ }
+
+ private String gc(String wkts)
+ {
+ return format("GEOMETRYCOLLECTION (%s)", wkts);
+ }
+}
diff --git a/src/test/java/com/esri/core/geometry/TestOGCReduceFromMulti.java b/src/test/java/com/esri/core/geometry/TestOGCReduceFromMulti.java
new file mode 100644
index 00000000..f47c817c
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestOGCReduceFromMulti.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed 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 com.esri.core.geometry;
+
+import org.junit.Test;
+
+import static com.esri.core.geometry.ogc.OGCGeometry.fromText;
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+
+public class TestOGCReduceFromMulti
+{
+ @Test
+ public void testPoint()
+ {
+ assertReduceFromMulti("POINT (1 2)", "POINT (1 2)");
+ assertReduceFromMulti("POINT EMPTY", "POINT EMPTY");
+ assertReduceFromMulti("MULTIPOINT (1 2)", "POINT (1 2)");
+ assertReduceFromMulti("MULTIPOINT (1 2, 3 4)", "MULTIPOINT ((1 2), (3 4))");
+ assertReduceFromMulti("MULTIPOINT EMPTY", "POINT EMPTY");
+ }
+
+ @Test
+ public void testLineString()
+ {
+ assertReduceFromMulti("LINESTRING (0 0, 1 1, 2 3)", "LINESTRING (0 0, 1 1, 2 3)");
+ assertReduceFromMulti("LINESTRING EMPTY", "LINESTRING EMPTY");
+ assertReduceFromMulti("MULTILINESTRING ((0 0, 1 1, 2 3))", "LINESTRING (0 0, 1 1, 2 3)");
+ assertReduceFromMulti("MULTILINESTRING ((0 0, 1 1, 2 3), (4 4, 5 5))", "MULTILINESTRING ((0 0, 1 1, 2 3), (4 4, 5 5))");
+ assertReduceFromMulti("MULTILINESTRING EMPTY", "LINESTRING EMPTY");
+ }
+
+ @Test
+ public void testPolygon()
+ {
+ assertReduceFromMulti("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ assertReduceFromMulti("POLYGON EMPTY", "POLYGON EMPTY");
+ assertReduceFromMulti("MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))", "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+ assertReduceFromMulti("MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((2 2, 3 2, 3 3, 2 2)))", "MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((2 2, 3 2, 3 3, 2 2)))");
+ assertReduceFromMulti("MULTIPOLYGON EMPTY", "POLYGON EMPTY");
+ }
+
+ @Test
+ public void testGeometryCollection()
+ {
+ assertReduceFromMulti(gc("POINT (1 2)"), "POINT (1 2)");
+ assertReduceFromMulti(gc("MULTIPOINT (1 2)"), "POINT (1 2)");
+ assertReduceFromMulti(gc(gc("POINT (1 2)")), "POINT (1 2)");
+ assertReduceFromMulti(gc("POINT EMPTY"), "POINT EMPTY");
+
+ assertReduceFromMulti(gc("LINESTRING (0 0, 1 1, 2 3)"), "LINESTRING (0 0, 1 1, 2 3)");
+ assertReduceFromMulti(gc("POLYGON ((0 0, 1 0, 1 1, 0 0))"), "POLYGON ((0 0, 1 0, 1 1, 0 0))");
+
+ assertReduceFromMulti(gc("POINT (1 2), LINESTRING (0 0, 1 1, 2 3)"), gc("POINT (1 2), LINESTRING (0 0, 1 1, 2 3)"));
+
+ assertReduceFromMulti("GEOMETRYCOLLECTION EMPTY", "GEOMETRYCOLLECTION EMPTY");
+ assertReduceFromMulti(gc("GEOMETRYCOLLECTION EMPTY"), "GEOMETRYCOLLECTION EMPTY");
+ }
+
+ private void assertReduceFromMulti(String wkt, String reducedWkt)
+ {
+ assertEquals(reducedWkt, fromText(wkt).reduceFromMulti().asText());
+ }
+
+ private String gc(String wkts)
+ {
+ return format("GEOMETRYCOLLECTION (%s)", wkts);
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestOffset.java b/src/test/java/com/esri/core/geometry/TestOffset.java
similarity index 81%
rename from unittest/com/esri/core/geometry/TestOffset.java
rename to src/test/java/com/esri/core/geometry/TestOffset.java
index 7ef61a01..385e3504 100644
--- a/unittest/com/esri/core/geometry/TestOffset.java
+++ b/src/test/java/com/esri/core/geometry/TestOffset.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import com.esri.core.geometry.OperatorOffset.JoinType;
@@ -143,8 +167,6 @@ public void OffsetPolygon_(double distance, JoinType joins) {
Geometry outputGeom = offset.execute(polygon, null, distance, joins, 2,
0, null);
- System.out.println(GeometryUtils.getJSonStringFromGeometry(outputGeom,
- null));
assertNotNull(outputGeom);
if (distance > 2) {
diff --git a/unittest/com/esri/core/geometry/TestPoint.java b/src/test/java/com/esri/core/geometry/TestPoint.java
similarity index 50%
rename from unittest/com/esri/core/geometry/TestPoint.java
rename to src/test/java/com/esri/core/geometry/TestPoint.java
index 1a0bb15c..c30f612f 100644
--- a/unittest/com/esri/core/geometry/TestPoint.java
+++ b/src/test/java/com/esri/core/geometry/TestPoint.java
@@ -1,7 +1,33 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import java.util.Random;
+
import junit.framework.TestCase;
+
import org.junit.Test;
public class TestPoint extends TestCase {
@@ -19,8 +45,36 @@ protected void tearDown() throws Exception {
public void testPt() {
Point pt = new Point();
assertTrue(pt.isEmpty());
+ assertTrue(Double.isNaN(pt.getX()));
+ assertTrue(Double.isNaN(pt.getY()));
+ assertTrue(Double.isNaN(pt.getM()));
+ assertTrue(pt.getZ() == 0);
+ Point pt1 = new Point();
+ assertTrue(pt.equals(pt1));
+ int hash1 = pt.hashCode();
pt.setXY(10, 2);
assertFalse(pt.isEmpty());
+ assertTrue(pt.getX() == 10);
+ assertTrue(pt.getY() == 2);
+ assertTrue(pt.getXY().equals(new Point2D(10, 2)));
+ assertTrue(pt.getXYZ().x == 10);
+ assertTrue(pt.getXYZ().y == 2);
+ assertTrue(pt.getXYZ().z == 0);
+ assertFalse(pt.equals(pt1));
+ pt.copyTo(pt1);
+ assertTrue(pt.equals(pt1));
+ int hash2 = pt.hashCode();
+ assertFalse(hash1 == hash2);
+ pt.setZ(5);
+ assertFalse(pt.equals(pt1));
+ pt.copyTo(pt1);
+ assertTrue(pt.equals(pt1));
+ assertFalse(hash1 == pt.hashCode());
+ assertFalse(hash2 == pt.hashCode());
+ assertTrue(pt.hasZ());
+ assertTrue(pt.getZ() == 5);
+ assertTrue(pt.hasAttribute(VertexDescription.Semantics.Z));
+ pt.toString();
}
@Test
@@ -41,7 +95,6 @@ public void testEnvelope2000() {
fullExtent.merge(geomExtent);
}
long endTime = System.nanoTime();
- System.out.println((endTime - startTime) / 1.0e6);
}
}
@@ -110,5 +163,75 @@ public void testCopy() {
copyPt = (Point) pt.copy();
assertTrue(copyPt.equals(pt));
assertTrue(copyPt.getXY().isEqual(new Point2D(11, 13)));
+
+ assertTrue(copyPt.getXY().equals((Object)new Point2D(11, 13)));
}
+
+ @Test
+ public void testEnvelope2D_corners() {
+ Envelope2D env = new Envelope2D(0, 1, 2, 3);
+ assertFalse(env.equals(null));
+ assertTrue(env.equals((Object)new Envelope2D(0, 1, 2, 3)));
+
+ Point2D pt2D = env.getLowerLeft();
+ assertTrue(pt2D.equals(Point2D.construct(0, 1)));
+ pt2D = env.getUpperLeft();
+ assertTrue(pt2D.equals(Point2D.construct(0, 3)));
+ pt2D = env.getUpperRight();
+ assertTrue(pt2D.equals(Point2D.construct(2, 3)));
+ pt2D = env.getLowerRight();
+ assertTrue(pt2D.equals(Point2D.construct(2, 1)));
+
+ {
+ Point2D[] corners = new Point2D[4];
+ env.queryCorners(corners);
+ assertTrue(corners[0].equals(Point2D.construct(0, 1)));
+ assertTrue(corners[1].equals(Point2D.construct(0, 3)));
+ assertTrue(corners[2].equals(Point2D.construct(2, 3)));
+ assertTrue(corners[3].equals(Point2D.construct(2, 1)));
+
+ env.queryCorners(corners);
+ assertTrue(corners[0].equals(env.queryCorner(0)));
+ assertTrue(corners[1].equals(env.queryCorner(1)));
+ assertTrue(corners[2].equals(env.queryCorner(2)));
+ assertTrue(corners[3].equals(env.queryCorner(3)));
+ }
+
+ {
+ Point2D[] corners = new Point2D[4];
+ env.queryCornersReversed(corners);
+ assertTrue(corners[0].equals(Point2D.construct(0, 1)));
+ assertTrue(corners[1].equals(Point2D.construct(2, 1)));
+ assertTrue(corners[2].equals(Point2D.construct(2, 3)));
+ assertTrue(corners[3].equals(Point2D.construct(0, 3)));
+
+ env.queryCornersReversed(corners);
+ assertTrue(corners[0].equals(env.queryCorner(0)));
+ assertTrue(corners[1].equals(env.queryCorner(3)));
+ assertTrue(corners[2].equals(env.queryCorner(2)));
+ assertTrue(corners[3].equals(env.queryCorner(1)));
+ }
+
+ assertTrue(env.getCenter().equals(Point2D.construct(1, 2)));
+
+ assertFalse(env.containsExclusive(env.getUpperLeft()));
+ assertTrue(env.contains(env.getUpperLeft()));
+ assertTrue(env.containsExclusive(env.getCenter()));
+ }
+
+ @Test
+ public void testReplaceNaNs() {
+ Envelope env = new Envelope();
+ Point pt = new Point();
+ pt.setXY(1, 2);
+ pt.setZ(Double.NaN);
+ pt.queryEnvelope(env);
+ pt.replaceNaNs(VertexDescription.Semantics.Z, 5);
+ assertTrue(pt.equals(new Point(1, 2, 5)));
+
+ assertTrue(env.hasZ());
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).isEmpty());
+ env.replaceNaNs(VertexDescription.Semantics.Z, 5);
+ assertTrue(env.queryInterval(VertexDescription.Semantics.Z, 0).equals(new Envelope1D(5, 5)));
+ }
}
diff --git a/unittest/com/esri/core/geometry/TestPolygon.java b/src/test/java/com/esri/core/geometry/TestPolygon.java
similarity index 76%
rename from unittest/com/esri/core/geometry/TestPolygon.java
rename to src/test/java/com/esri/core/geometry/TestPolygon.java
index 450ac083..2c4b0b4f 100644
--- a/unittest/com/esri/core/geometry/TestPolygon.java
+++ b/src/test/java/com/esri/core/geometry/TestPolygon.java
@@ -1,6 +1,33 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
+import java.io.IOException;
+
import junit.framework.TestCase;
+
import org.junit.Test;
import com.esri.core.geometry.ogc.OGCGeometry;
@@ -66,8 +93,9 @@ public void testCreation1() {
@SuppressWarnings("unused")
int number = poly.getStateFlag();
Envelope env = new Envelope(1000, 2000, 1010, 2010);
-
+ env.toString();
poly.addEnvelope(env, false);
+ poly.toString();
number = poly.getStateFlag();
assertTrue(Math.abs(poly.calculateArea2D() - 100) < 1e-12);
assertTrue(Math.abs(poly.calculateLength2D() - 40) < 1e-12);
@@ -77,147 +105,6 @@ public void testCreation1() {
number = poly.getStateFlag();
assertTrue(Math.abs(poly.calculateArea2D() + 100) < 1e-12);
number = poly.getStateFlag();
-
- // FIXME
- // env.queryCoornerByVal(index, ptDst)
- // SPtrOfArrayOf(Point2D) corners = new ArrayOf(Point2D)(4);
- // env.QueryCorners(corners);
- // poly.setEmpty();
- // poly.addPath(corners, corners.length, true);
-
- // assertTrue(Math.abs(poly.calculateArea2D() - 100) < 1e-12);
-
- // {
- // SegmentIterator segIter1 = poly.querySegmentIterator();
- // while (segIter1.nextPath())
- // {
- // while (segIter1.hasNextSegment())
- // {
- // Segment seg = segIter1.nextSegment();
- // double len = seg.calculateLength2D();
- // assertTrue(len != 0);
- // }
- // }
- // }
-
- // env.QueryCornersReversed(corners);
- // poly.setEmpty();
- // poly.addPath(corners, corners.length, true);
- // assertTrue(Math.abs(poly.calculateArea2D() + 100) < 1e-12);
- //
- // poly.setEmpty();
- // env.SetCoords(-200, -200, 200, 200);
- // poly.addEnvelope(env, false);
- // env.SetCoords(-100, -100, 100, 100);
- // poly.addEnvelope(env, true);
- // assertTrue(Math.abs(poly.calculateArea2D() - (400 * 400 - 200 * 200))
- // < 1e-12);
- // assertTrue(Math.abs(poly.calculateRingArea2D(1) - (- 200 * 200)) <
- // 1e-12);
- // assertTrue(Math.abs(poly.calculateRingArea2D(0) - (400 * 400)) <
- // 1e-12);
- // assertTrue(Math.abs(poly.calculateLength2D() - (400 * 4 + 200 * 4)) <
- // 1e-12);
-
- // test CopyTo;
- // Polygon polyCopy = new Polygon();
- // poly.copyTo(polyCopy);
- // assertTrue(poly.calculateArea2D() == polyCopy.calculateArea2D());
- // assertTrue(poly.calculateRingArea2D(1) ==
- // polyCopy.calculateRingArea2D(1));
- // assertTrue(poly.calculateRingArea2D(1) ==
- // polyCopy.calculateRingArea2D(1));
- // assertTrue(poly.calculateLength2D() == polyCopy.calculateLength2D());
- // }
- //
- // Polygon poly = new Polygon();
- // poly.startPath(10, 1);
- // poly.lineTo(15, 20);
- // poly.lineTo(30, 14);
- // poly.lineTo(60, 144);
- //
- // assertTrue(poly.getPointCount() == 4);
- // assertTrue(poly.getPathCount() == 1);
- // SPtrOfArrayOf(Point2D) xy = poly.getCoordinates2D();
- // assertTrue(xy[0].x == 10); assertTrue(xy[0].y == 1);
- // assertTrue(xy[1].x == 15); assertTrue(xy[1].y == 20);
- // assertTrue(xy[2].x == 30); assertTrue(xy[2].y == 14);
- // assertTrue(xy[3].x == 60); assertTrue(xy[3].y == 144);
-
- // poly.startPath(20, 13);
- // poly.lineTo(150, 120);
- // poly.lineTo(300, 414);
- // poly.lineTo(610, 14);
- // poly.lineTo(6210, 140);
- //
- // assertTrue(poly.getPointCount() == 9);
- // assertTrue(poly.getPathCount() == 2);
- // assertTrue(poly.isClosedPath(0));
- // assertTrue(poly.isClosedPath(1));
- // assertFalse(poly.hasNonLinearSegments(0));
- // assertFalse(poly.hasNonLinearSegments(1));
- //
- // {
- // SegmentIterator segIter1 = poly.querySegmentIterator();
- // while (segIter1.nextPath())
- // {
- // while (segIter1.hasNextSegment())
- // {
- // Segment seg = segIter1.nextSegment();
- // double len = seg.calculateLength2D();
- // assertTrue(len != 0);
- // }
- // }
- // }
-
- // {
- // MultiPathImpl::Pointer mpImpl =
- // (MultiPathImpl::Pointer)poly->_GetImpl();
- // AttributeStreamBase xy =
- // mpImpl.getAttributeStreamRef(enum_value2(VertexDescription,
- // Semantics, POSITION));
- // double x = xy.readAsDbl(2 * 0);
- // double y = xy.readAsDbl(2 * 0 + 1);
- // assertTrue(x == 10); assertTrue(y == 1);
- // x = xy.readAsDbl(2 * 1);
- // y = xy.readAsDbl(2 * 1 + 1);
- // assertTrue(x == 15); assertTrue(y == 20);
- // x = xy.readAsDbl(2 * 2);
- // y = xy.readAsDbl(2 * 2 + 1);
- // assertTrue(x == 30); assertTrue(y == 14);
- // x = xy.readAsDbl(2 * 3);
- // y = xy.readAsDbl(2 * 3 + 1);
- // assertTrue(x == 60); assertTrue(y == 144);
- //
- // x = xy.readAsDbl(2 * 4);
- // y = xy.readAsDbl(2 * 4 + 1);
- // assertTrue(x == 20); assertTrue(y == 13);
- // x = xy.readAsDbl(2 * 5);
- // y = xy.readAsDbl(2 * 5 + 1);
- // assertTrue(x == 150); assertTrue(y == 120);
- // x = xy.readAsDbl(2 * 6);
- // y = xy.readAsDbl(2 * 6 + 1);
- // assertTrue(x == 300); assertTrue(y == 414);
- // x = xy.readAsDbl(2 * 7);
- // y = xy.readAsDbl(2 * 7 + 1);
- // assertTrue(x == 610); assertTrue(y == 14);
- // x = xy.readAsDbl(2 * 8);
- // y = xy.readAsDbl(2 * 8 + 1);
- // assertTrue(x == 6210); assertTrue(y == 140);
- //
- // assertTrue(Math.abs(mpImpl.calculateArea2D() - 71752.5) < 1e-6);
- // assertTrue(Math.abs(mpImpl.calculateLength2D() - 13117.917692934170)
- // < 1e-6);
- //
- // AttributeStreamOfIndexType parts = mpImpl.getPathStreamRef();
- // assertTrue(parts.size() == 3);
- // assertTrue(parts.read(0) == 0);
- // assertTrue(parts.read(1) == 4);
- // assertTrue(parts.read(2) == 9);
- // assertTrue(mpImpl.getSegmentIndexStreamRef() == NULLPTR);
- // assertTrue(mpImpl.getSegmentFlagsStreamRef() == NULLPTR);
- // assertTrue(mpImpl.getSegmentDataStreamRef() == NULLPTR);
- // }
}
@Test
@@ -299,17 +186,6 @@ public void testCreation2() {
poly2.lineTo(100, 10);
poly2.lineTo(100, 100);
poly2.lineTo(10, 100);
-
- // FIXME
- // RasterizedGeometry2D rg =
- // RasterizedGeometry2D.create((Geometry)poly2, 0, 1024);
- // RasterizedGeometry2D.HitType res = null;
- // res = rg.queryPointInGeometry(7, 10);
- // assertTrue(res == RasterizedGeometry2D.HitType.Outside);
- // res = rg.queryPointInGeometry(10, 10);
- // assertTrue(res == RasterizedGeometry2D.HitType.Border);
- // res = rg.queryPointInGeometry(50, 50);
- // assertTrue(res == RasterizedGeometry2D.HitType.Inside);
}
{
@@ -933,17 +809,6 @@ public void testInsertPath() {
Point2D pt3 = poly.getXY(3);
assertTrue(pt3.x == 16 && pt3.y == 21);
- // SPtrOfArrayOf(Point2D) points = NULLPTR;
- // FIXME
- // poly.insertPath(1, points, 0, 0, true);
- // assertTrue(poly.getPathCount() == 5);
- // assertTrue(poly.getPathStart(0) == 0);
- // assertTrue(poly.getPathStart(1) == 4);
- // assertTrue(poly.getPathStart(2) == 4);
- // assertTrue(poly.getPathStart(3) == 8);
- // assertTrue(poly.getPathStart(4) == 12);
- // assertTrue(poly.getPointCount() == 16);
-
Point pt2d = new Point(-27, -27);
poly.insertPoint(1, 0, pt2d);
@@ -953,44 +818,6 @@ public void testInsertPath() {
assertTrue(poly.getPathStart(2) == 9);
assertTrue(poly.getPathStart(3) == 13);
assertTrue(poly.getPointCount() == 17);
-
- // points = new ArrayOf(Point2D)(3);
- // points[0].x = 17;
- // points[0].y = 17;
- // points[1].x = 19;
- // points[1].y = 19;
- // points[2].x = 23;
- // points[2].y = 23;
-
- // poly.insertPath(1, points, 0, 3, true);
- // assertTrue(poly.getPathCount() == 6);
- // assertTrue(poly.getPathStart(0) == 0);
- // assertTrue(poly.getPathStart(1) == 4);
- // assertTrue(poly.getPathStart(2) == 7);
- // assertTrue(poly.getPathStart(3) == 8);
- // assertTrue(poly.getPathStart(4) == 12);
- // assertTrue(poly.getPathStart(5) == 16);
- // assertTrue(poly.getPointCount() == 20);
-
- // Point2D *pointsNative = new Point2D[3];
- // pointsNative[0].x = 29;
- // pointsNative[0].y = 29;
- // pointsNative[1].x = 31;
- // pointsNative[1].y = 31;
- // pointsNative[2].x = 37;
- // pointsNative[2].y = 37;
-
- // FIXME
- // poly.insertPath(1, pointsNative, 0, 3, true);
- // assertTrue(poly.getPathCount() == 7);
- // assertTrue(poly.getPathStart(0) == 0);
- // assertTrue(poly.getPathStart(1) == 4);
- // assertTrue(poly.getPathStart(2) == 7);
- // assertTrue(poly.getPathStart(3) == 10);
- // assertTrue(poly.getPathStart(4) == 11);
- // assertTrue(poly.getPathStart(5) == 15);
- // assertTrue(poly.getPathStart(6) == 19);
- // assertTrue(poly.getPointCount() == 23);
}
@Test
@@ -1222,99 +1049,13 @@ public void testInsertPointsFromArray() {
poly1.lineTo(300, 147);
poly1.lineTo(6000, 1447);
- // FIXME
- // poly1.insertPoints(1, 2, arr, 1, 3, true); //forward
-
assertTrue(poly1.getPathCount() == 2);
assertTrue(poly1.getPathStart(1) == 4);
assertTrue(poly1.isClosedPath(0));
assertTrue(poly1.isClosedPath(1));
- // assertTrue(poly1.getPointCount() == 11);
- // assertTrue(poly1.getPathSize(1) == 7);
- // Point2D ptOut;
- // ptOut = poly1.getXY(5);
- // assertTrue(ptOut.x == 1250 && ptOut.y == 207);
- // ptOut = poly1.getXY(6);
- // assertTrue(ptOut.x == 15 && ptOut.y == 20);
- // ptOut = poly1.getXY(7);
- // assertTrue(ptOut.x == 300 && ptOut.y == 14);
- // ptOut = poly1.getXY(8);
- // assertTrue(ptOut.x == 314 && ptOut.y == 217);
- // ptOut = poly1.getXY(9);
- // assertTrue(ptOut.x == 300 && ptOut.y == 147);
- // ptOut = poly1.getXY(10);
- // assertTrue(ptOut.x == 6000 && ptOut.y == 1447);
-
- // Point2D *points = new Point2D[3];
- // points[0].x = 17;
- // points[0].y = 17;
- // points[1].x = 19;
- // points[1].y = 19;
- // points[2].x = 23;
- // points[2].y = 23;
-
- // FIXME
- // poly1.insertPoints(1, 2, points, 0, 3, true);
- // assertTrue(poly1.getPathCount() == 2);
- // assertTrue(poly1.getPathStart(1) == 4);
- // assertTrue(poly1.getPointCount() == 14);
- // assertTrue(poly1.getPathSize(1) == 10);
-
- // ptOut = poly1.getXY(5);
- // assertTrue(ptOut.x == 1250 && ptOut.y == 207);
- // ptOut = poly1.getXY(6);
- // assertTrue(ptOut.x == 17 && ptOut.y == 17);
- // ptOut = poly1.getXY(7);
- // assertTrue(ptOut.x == 19 && ptOut.y == 19);
- // ptOut = poly1.getXY(8);
- // assertTrue(ptOut.x == 23 && ptOut.y == 23);
- // ptOut = poly1.getXY(9);
- // assertTrue(ptOut.x == 15 && ptOut.y == 20);
- // ptOut = poly1.getXY(10);
- // assertTrue(ptOut.x == 300 && ptOut.y == 14);
}
{// Test reversed insertion of an array of Point2D
- // ArrayOf(Point2D) arr = new ArrayOf(Point2D)(5);
- // arr[0].SetCoords(10, 1);
- // arr[1].SetCoords(15, 20);
- // arr[2].SetCoords(300, 14);
- // arr[3].SetCoords(314, 217);
- // arr[4].SetCoords(60, 144);
-
- // Polygon poly1 = new Polygon();
- // poly1.startPath(1, 17);
- // poly1.lineTo(1, 207);
- // poly1.lineTo(3, 147);
- // poly1.lineTo(6, 1447);
- //
- // poly1.startPath(1000, 17);
- // poly1.lineTo(1250, 207);
- // poly1.lineTo(300, 147);
- // poly1.lineTo(6000, 1447);
- //
- // //FIXME
- // //poly1.insertPoints(1, 2, arr, 1, 3, false); //reversed
- //
- // assertTrue(poly1.getPathCount() == 2);
- // assertTrue(poly1.getPathStart(1) == 4);
- // assertTrue(poly1.isClosedPath(0));
- // assertTrue(poly1.isClosedPath(1));
- // assertTrue(poly1.getPointCount() == 11);
- // assertTrue(poly1.getPathSize(1) == 7);
- // Point2D ptOut;
- // ptOut = poly1.getXY(5);
- // assertTrue(ptOut.x == 1250 && ptOut.y == 207);
- // ptOut = poly1.getXY(6);
- // assertTrue(ptOut.x == 314 && ptOut.y == 217);
- // ptOut = poly1.getXY(7);
- // assertTrue(ptOut.x == 300 && ptOut.y == 14);
- // ptOut = poly1.getXY(8);
- // assertTrue(ptOut.x == 15 && ptOut.y == 20);
- // ptOut = poly1.getXY(9);
- // assertTrue(ptOut.x == 300 && ptOut.y == 147);
- // ptOut = poly1.getXY(10);
- // assertTrue(ptOut.x == 6000 && ptOut.y == 1447);
}
}
@@ -1361,8 +1102,12 @@ public void testCR177477getPathEnd() {
// int endIndex = pg.getPathEnd(pathCount - 1);
Line line = new Line();
+ line.toString();
+
line.setStart(new Point(0, 0));
line.setEnd(new Point(1, 0));
+
+ line.toString();
double geoLength = GeometryEngine.geodesicDistanceOnWGS84(new Point(0,
0), new Point(1, 0));
@@ -1425,4 +1170,159 @@ public void testBoundary() {
assertTrue(s
.equals("MULTILINESTRING ((-10 -10, 10 -10, 10 10, -10 10, -10 -10), (-5 -5, -5 5, 5 5, 5 -5, -5 -5))"));
}
+
+ @Test
+ public void testReplaceNaNs() {
+ {
+ MultiPoint mp = new MultiPoint();
+ Point pt = new Point();
+ pt.setXY(1, 2);
+ pt.setZ(Double.NaN);
+ mp.add(pt);
+ pt = new Point();
+ pt.setXY(11, 12);
+ pt.setZ(3);
+ mp.add(pt);
+
+ mp.replaceNaNs(VertexDescription.Semantics.Z, 5);
+ assertTrue(mp.getPoint(0).equals(new Point(1, 2, 5)));
+ assertTrue(mp.getPoint(1).equals(new Point(11, 12, 3)));
+ }
+
+ {
+ Polygon mp = new Polygon();
+ Point pt = new Point();
+ pt.setXY(1, 2);
+ pt.setZ(Double.NaN);
+ mp.startPath(pt);
+ pt = new Point();
+ pt.setXY(11, 12);
+ pt.setZ(3);
+ mp.lineTo(pt);
+
+ mp.replaceNaNs(VertexDescription.Semantics.Z, 5);
+ assertTrue(mp.getPoint(0).equals(new Point(1, 2, 5)));
+ assertTrue(mp.getPoint(1).equals(new Point(11, 12, 3)));
+ }
+
+ {
+ Polygon mp = new Polygon();
+ Point pt = new Point();
+ pt.setXY(1, 2);
+ pt.setM(Double.NaN);
+ mp.startPath(pt);
+ pt = new Point();
+ pt.setXY(11, 12);
+ pt.setM(3);
+ mp.lineTo(pt);
+
+ mp.replaceNaNs(VertexDescription.Semantics.M, 5);
+ Point p = new Point(1, 2); p.setM(5);
+ boolean b = mp.getPoint(0).equals(p);
+ assertTrue(b);
+ p = new Point(11, 12); p.setM(3);
+ b = mp.getPoint(1).equals(p);
+ assertTrue(b);
+ }
+
+ }
+
+ @Test
+ public void testPolygon2PolygonFails() {
+ OperatorFactoryLocal factory = OperatorFactoryLocal.getInstance();
+ OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory
+ .getOperator(Operator.Type.ExportToGeoJson);
+ String result = exporter.execute(birmingham());
+
+ OperatorImportFromGeoJson importer = (OperatorImportFromGeoJson) factory
+ .getOperator(Operator.Type.ImportFromGeoJson);
+ MapGeometry mapGeometry = importer.execute(
+ GeoJsonImportFlags.geoJsonImportDefaults,
+ Geometry.Type.Polygon, result, null);
+ Polygon polygon = (Polygon) mapGeometry.getGeometry();
+ assertEquals(birmingham(), polygon);
+ }
+
+ @Test
+ public void testPolygon2PolygonFails2() {
+ String birminghamGeojson = GeometryEngine
+ .geometryToGeoJson(birmingham());
+ MapGeometry returnedGeometry = GeometryEngine.geoJsonToGeometry(
+ birminghamGeojson, GeoJsonImportFlags.geoJsonImportDefaults,
+ Geometry.Type.Polygon);
+ Polygon polygon = (Polygon) returnedGeometry.getGeometry();
+ assertEquals(polygon, birmingham());
+ }
+
+ @Test
+ public void testPolygon2PolygonWorks() {
+ String birminghamGeojson = GeometryEngine
+ .geometryToGeoJson(birmingham());
+ MapGeometry returnedGeometry = GeometryEngine.geoJsonToGeometry(
+ birminghamGeojson, GeoJsonImportFlags.geoJsonImportDefaults,
+ Geometry.Type.Polygon);
+ Polygon polygon = (Polygon) returnedGeometry.getGeometry();
+ assertEquals(polygon.toString(), birmingham().toString());
+ }
+
+ @Test
+ public void testPolygon2Polygon2Works() {
+ String birminghamJson = GeometryEngine.geometryToJson(4326,
+ birmingham());
+ MapGeometry returnedGeometry = GeometryEngine
+ .jsonToGeometry(birminghamJson);
+ Polygon polygon = (Polygon) returnedGeometry.getGeometry();
+ assertEquals(polygon, birmingham());
+ String s = polygon.toString();
+ }
+
+ @Test
+ public void testSegmentIteratorCrash() {
+ Polygon poly = new Polygon();
+
+ // clockwise => outer ring
+ poly.startPath(0, 0);
+ poly.lineTo(-0.5, 0.5);
+ poly.lineTo(0.5, 1);
+ poly.lineTo(1, 0.5);
+ poly.lineTo(0.5, 0);
+
+ // hole
+ poly.startPath(0.5, 0.2);
+ poly.lineTo(0.6, 0.5);
+ poly.lineTo(0.2, 0.9);
+ poly.lineTo(-0.2, 0.5);
+ poly.lineTo(0.1, 0.2);
+ poly.lineTo(0.2, 0.3);
+
+ // island
+ poly.startPath(0.1, 0.7);
+ poly.lineTo(0.3, 0.7);
+ poly.lineTo(0.3, 0.4);
+ poly.lineTo(0.1, 0.4);
+
+ assertEquals(poly.getSegmentCount(), 15);
+ assertEquals(poly.getPathCount(), 3);
+ SegmentIterator segmentIterator = poly.querySegmentIterator();
+ int paths = 0;
+ int segments = 0;
+ while (segmentIterator.nextPath()) {
+ paths++;
+ Segment segment;
+ while (segmentIterator.hasNextSegment()) {
+ segment = segmentIterator.nextSegment();
+ segments++;
+ }
+ }
+ assertEquals(paths, 3);
+ assertEquals(segments, 15);
+ }
+
+ private static Polygon birmingham() {
+ Polygon poly = new Polygon();
+ poly.addEnvelope(new Envelope(-1.954245, 52.513531, -1.837357,
+ 52.450123), false);
+ poly.addEnvelope(new Envelope(0, 0, 1, 1), false);
+ return poly;
+ }
}
diff --git a/unittest/com/esri/core/geometry/TestPolygonUtils.java b/src/test/java/com/esri/core/geometry/TestPolygonUtils.java
similarity index 85%
rename from unittest/com/esri/core/geometry/TestPolygonUtils.java
rename to src/test/java/com/esri/core/geometry/TestPolygonUtils.java
index 16bc5215..2967d2f7 100644
--- a/unittest/com/esri/core/geometry/TestPolygonUtils.java
+++ b/src/test/java/com/esri/core/geometry/TestPolygonUtils.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
diff --git a/unittest/com/esri/core/geometry/TestProximity2D.java b/src/test/java/com/esri/core/geometry/TestProximity2D.java
similarity index 82%
rename from unittest/com/esri/core/geometry/TestProximity2D.java
rename to src/test/java/com/esri/core/geometry/TestProximity2D.java
index a0766cd5..9f6cd184 100644
--- a/unittest/com/esri/core/geometry/TestProximity2D.java
+++ b/src/test/java/com/esri/core/geometry/TestProximity2D.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
@@ -130,6 +154,18 @@ public void testProximity_2D_1() {
true);
resultPoint0 = result0.getCoordinate();
assertTrue(resultPoint0.getX() == 0.0 && resultPoint0.getY() == 2.0);
+
+ Polygon pp = new Polygon();
+ pp.startPath(0, 0);
+ pp.lineTo(0, 10);
+ pp.lineTo(10, 10);
+ pp.lineTo(10, 0);
+
+ inputPoint.setXY(15, -5);
+
+ result0 = proximityOp.getNearestCoordinate(pp, inputPoint, true, true);
+ boolean is_right = result0.isRightSide();
+ assertTrue(!is_right);
}
Polygon MakePolygon() {
@@ -227,13 +263,24 @@ public static void testProximity2D_3() {
point.setXY(-110, 20);
Proximity2DResult result = proximity.getNearestCoordinate(polygon,
point, false);
- System.out.println("The closest coordinate is "
- + result.getCoordinate());
- System.out.println("The closest point is " + result.getDistance());
Point point2 = new Point();
point2.setXY(-120, 12);
@SuppressWarnings("unused")
Proximity2DResult[] results = proximity.getNearestVertices(polygon,
point2, 10, 12);
}
+
+ @Test
+ public static void testCR254240() {
+ OperatorProximity2D proximityOp = OperatorProximity2D.local();
+
+ Point inputPoint = new Point(-12, 12);
+ Polyline line = new Polyline();
+ line.startPath(-10, 0);
+ line.lineTo(0, 0);
+
+ Proximity2DResult result = proximityOp.getNearestCoordinate(line,
+ inputPoint, false, true);
+ assertTrue(result.isRightSide() == false);
+ }
}
diff --git a/src/test/java/com/esri/core/geometry/TestQuadTree.java b/src/test/java/com/esri/core/geometry/TestQuadTree.java
new file mode 100644
index 00000000..9c4800ad
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestQuadTree.java
@@ -0,0 +1,530 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.HashMap;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+public class TestQuadTree extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public static void test1() {
+
+ {
+ QuadTree quad_tree = new QuadTree(Envelope2D.construct(-10, -10, 10, 10), 8);
+
+ QuadTree.QuadTreeIterator qt = quad_tree.getIterator(true);
+ assertTrue(qt.next() == -1);
+
+ qt.resetIterator(Envelope2D.construct(0, 0, 0, 0), 0);
+
+ assertTrue(quad_tree.getIntersectionCount(Envelope2D.construct(0, 0, 0, 0), 0, 10) == 0);
+ assertTrue(quad_tree.getElementCount() == 0);
+ }
+
+ Polyline polyline;
+ polyline = makePolyline();
+
+ MultiPathImpl polylineImpl = (MultiPathImpl) polyline._getImpl();
+ QuadTree quadtree = buildQuadTree_(polylineImpl, false);
+
+ Line queryline = new Line(34, 9, 66, 46);
+ QuadTree.QuadTreeIterator qtIter = quadtree.getIterator();
+ assertTrue(qtIter.next() == -1);
+
+ qtIter.resetIterator(queryline, 0.0);
+
+ int element_handle = qtIter.next();
+ while (element_handle > 0) {
+ int index = quadtree.getElement(element_handle);
+ assertTrue(index == 6 || index == 8 || index == 14);
+ element_handle = qtIter.next();
+ }
+
+ Envelope2D envelope = new Envelope2D(34, 9, 66, 46);
+ Polygon queryPolygon = new Polygon();
+ queryPolygon.addEnvelope(envelope, true);
+
+ qtIter.resetIterator(queryline, 0.0);
+
+ element_handle = qtIter.next();
+ while (element_handle > 0) {
+ int index = quadtree.getElement(element_handle);
+ assertTrue(index == 6 || index == 8 || index == 14);
+ element_handle = qtIter.next();
+ }
+ }
+
+ @Test
+ public static void testQuadTreeWithDuplicates() {
+ int pass_count = 10;
+ int figure_size = 400;
+ int figure_size2 = 100;
+ Envelope extent1 = new Envelope();
+ extent1.setCoords(-100000, -100000, 100000, 100000);
+
+ RandomCoordinateGenerator generator1 = new RandomCoordinateGenerator(Math.max(figure_size, 10000), extent1, 0.001);
+ Random random = new Random(2013);
+ int rand_max = 32;
+
+ Polygon poly_red = new Polygon();
+ Polygon poly_blue = new Polygon();
+
+ int r = figure_size;
+
+ for (int c = 0; c < pass_count; c++) {
+ Point pt;
+ for (int j = 0; j < r; j++) {
+ int rand = random.nextInt(rand_max);
+ boolean b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
+ pt = generator1.GetRandomCoord();
+ if (j == 0 || b_random_new)
+ poly_blue.startPath(pt);
+ else
+ poly_blue.lineTo(pt);
+ }
+
+ Envelope2D env = new Envelope2D();
+
+ QuadTree quad_tree_blue = buildQuadTree_((MultiPathImpl) poly_blue._getImpl(), false);
+ QuadTree quad_tree_blue_duplicates = buildQuadTree_((MultiPathImpl) poly_blue._getImpl(), true);
+
+ Envelope2D e1 = quad_tree_blue.getDataExtent();
+ Envelope2D e2 = quad_tree_blue_duplicates.getDataExtent();
+ assertTrue(e1.equals(e2));
+ assertTrue(quad_tree_blue.getElementCount() == poly_blue.getSegmentCount());
+
+ SegmentIterator seg_iter_blue = poly_blue.querySegmentIterator();
+
+ poly_red.setEmpty();
+
+ r = figure_size2;
+ if (r < 3)
+ continue;
+
+ for (int j = 0; j < r; j++) {
+ int rand = random.nextInt(rand_max);
+ boolean b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
+ pt = generator1.GetRandomCoord();
+ if (j == 0 || b_random_new)
+ poly_red.startPath(pt);
+ else
+ poly_red.lineTo(pt);
+ }
+
+ QuadTree.QuadTreeIterator iterator = quad_tree_blue.getIterator();
+ SegmentIteratorImpl seg_iter_red = ((MultiPathImpl) poly_red._getImpl()).querySegmentIterator();
+
+ HashMap map1 = new HashMap(0);
+
+ int count = 0;
+ int intersections_per_query = 0;
+ while (seg_iter_red.nextPath()) {
+ while (seg_iter_red.hasNextSegment()) {
+ Segment segment_red = seg_iter_red.nextSegment();
+ segment_red.queryEnvelope2D(env);
+
+ iterator.resetIterator(env, 0.0);
+
+ int count_upper = 0;
+ int element_handle;
+ while ((element_handle = iterator.next()) != -1) {
+ count_upper++;
+ int index = quad_tree_blue.getElement(element_handle);
+ Boolean iter = (Boolean) map1.get(new Integer(index));
+ if (iter == null) {
+ count++;
+ map1.put(new Integer(index), new Boolean(true));
+ }
+
+ intersections_per_query++;
+ }
+
+ int intersection_count = quad_tree_blue.getIntersectionCount(env, 0.0, -1);
+ assertTrue(intersection_count == count_upper);
+ }
+ }
+
+ seg_iter_red.resetToFirstPath();
+
+ HashMap map2 = new HashMap(0);
+ QuadTree.QuadTreeIterator iterator_duplicates = quad_tree_blue_duplicates.getIterator();
+
+ int count_duplicates = 0;
+ int intersections_per_query_duplicates = 0;
+ while (seg_iter_red.nextPath()) {
+ while (seg_iter_red.hasNextSegment()) {
+ Segment segment_red = seg_iter_red.nextSegment();
+ segment_red.queryEnvelope2D(env);
+
+ iterator_duplicates.resetIterator(env, 0.0);
+
+ int count_lower = 0;
+ HashMap map_per_query = new HashMap(0);
+
+ int count_upper = 0;
+ int element_handle;
+ while ((element_handle = iterator_duplicates.next()) != -1) {
+ count_upper++;
+ int index = quad_tree_blue_duplicates.getElement(element_handle);
+ Boolean iter = (Boolean) map2.get(new Integer(index));
+ if (iter == null) {
+ count_duplicates++;
+ map2.put(new Integer(index), new Boolean(true));
+ }
+
+ Boolean iter_lower = (Boolean) map_per_query.get(index);
+ if (iter_lower == null) {
+ count_lower++;
+ intersections_per_query_duplicates++;
+ map_per_query.put(new Integer(index), new Boolean(true));
+ }
+
+ int q = quad_tree_blue_duplicates.getQuad(element_handle);
+ assertTrue(quad_tree_blue_duplicates.getSubTreeElementCount(q) >= quad_tree_blue_duplicates.getContainedSubTreeElementCount(q));
+ }
+
+ int intersection_count = quad_tree_blue_duplicates.getIntersectionCount(env, 0.0, -1);
+ boolean b_has_data = quad_tree_blue_duplicates.hasData(env, 0.0);
+ assertTrue(b_has_data || intersection_count == 0);
+ assertTrue(count_lower <= intersection_count && intersection_count <= count_upper);
+ assertTrue(count_upper <= 4 * count_lower);
+ }
+ }
+
+ assertTrue(count == count_duplicates);
+ assertTrue(intersections_per_query == intersections_per_query_duplicates);
+ }
+ }
+
+ @Test
+ public static void testSortedIterator() {
+ int pass_count = 10;
+ int figure_size = 400;
+ int figure_size2 = 100;
+ Envelope extent1 = new Envelope();
+ extent1.setCoords(-100000, -100000, 100000, 100000);
+
+ RandomCoordinateGenerator generator1 = new RandomCoordinateGenerator(Math.max(figure_size, 10000), extent1, 0.001);
+
+ Random random = new Random(2013);
+ int rand_max = 32;
+
+ Polygon poly_red = new Polygon();
+ Polygon poly_blue = new Polygon();
+
+ int r = figure_size;
+
+ for (int c = 0; c < pass_count; c++) {
+ Point pt;
+ for (int j = 0; j < r; j++) {
+ int rand = random.nextInt(rand_max);
+ boolean b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
+ pt = generator1.GetRandomCoord();
+ if (j == 0 || b_random_new)
+ poly_blue.startPath(pt);
+ else
+ poly_blue.lineTo(pt);
+ }
+
+ Envelope2D env = new Envelope2D();
+
+ QuadTree quad_tree_blue = buildQuadTree_((MultiPathImpl) poly_blue._getImpl(), false);
+
+ Envelope2D e1 = quad_tree_blue.getDataExtent();
+ assertTrue(quad_tree_blue.getElementCount() == poly_blue.getSegmentCount());
+
+ SegmentIterator seg_iter_blue = poly_blue.querySegmentIterator();
+
+ poly_red.setEmpty();
+
+ r = figure_size2;
+ if (r < 3)
+ continue;
+
+ for (int j = 0; j < r; j++) {
+ int rand = random.nextInt(rand_max);
+ boolean b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
+ pt = generator1.GetRandomCoord();
+ if (j == 0 || b_random_new)
+ poly_red.startPath(pt);
+ else
+ poly_red.lineTo(pt);
+ }
+
+ QuadTree.QuadTreeIterator iterator = quad_tree_blue.getIterator();
+ SegmentIteratorImpl seg_iter_red = ((MultiPathImpl) poly_red._getImpl()).querySegmentIterator();
+
+ HashMap map1 = new HashMap(0);
+
+ int count = 0;
+ int intersections_per_query = 0;
+ while (seg_iter_red.nextPath()) {
+ while (seg_iter_red.hasNextSegment()) {
+ Segment segment_red = seg_iter_red.nextSegment();
+ segment_red.queryEnvelope2D(env);
+
+ iterator.resetIterator(env, 0.0);
+
+ int count_upper = 0;
+ int element_handle;
+ while ((element_handle = iterator.next()) != -1) {
+ count_upper++;
+ int index = quad_tree_blue.getElement(element_handle);
+ Boolean iter = (Boolean) map1.get(index);
+ if (iter == null) {
+ count++;
+ map1.put(new Integer(index), new Boolean(true));
+ }
+
+ intersections_per_query++;
+ }
+
+ int intersection_count = quad_tree_blue.getIntersectionCount(env, 0.0, -1);
+ assertTrue(intersection_count == count_upper);
+ }
+ }
+
+ seg_iter_red.resetToFirstPath();
+
+ HashMap map2 = new HashMap(0);
+ QuadTree.QuadTreeIterator sorted_iterator = quad_tree_blue.getIterator(true);
+
+ int count_sorted = 0;
+ int intersections_per_query_sorted = 0;
+ while (seg_iter_red.nextPath()) {
+ while (seg_iter_red.hasNextSegment()) {
+ Segment segment_red = seg_iter_red.nextSegment();
+ segment_red.queryEnvelope2D(env);
+
+ sorted_iterator.resetIterator(env, 0.0);
+
+ int count_upper_sorted = 0;
+ int element_handle;
+ int last_index = -1;
+ while ((element_handle = sorted_iterator.next()) != -1) {
+ count_upper_sorted++;
+ int index = quad_tree_blue.getElement(element_handle);
+ assertTrue(last_index < index); // ensure the element handles are returned in sorted order
+ last_index = index;
+ Boolean iter = (Boolean) map2.get(index);
+ if (iter == null) {
+ count_sorted++;
+ map2.put(new Integer(index), new Boolean(true));
+ }
+
+ intersections_per_query_sorted++;
+ }
+
+ int intersection_count = quad_tree_blue.getIntersectionCount(env, 0.0, -1);
+ assertTrue(intersection_count == count_upper_sorted);
+ }
+ }
+
+ assertTrue(count == count_sorted);
+ assertTrue(intersections_per_query == intersections_per_query_sorted);
+ }
+ }
+
+ @Test
+ public static void test_perf_quad_tree() {
+ Envelope extent1 = new Envelope();
+ extent1.setCoords(-1000, -1000, 1000, 1000);
+
+ RandomCoordinateGenerator generator1 = new RandomCoordinateGenerator(1000, extent1, 0.001);
+ //HiResTimer timer;
+ for (int N = 16; N <= 1024/**1024*/; N *= 2) {
+ //timer.StartMeasurement();
+
+ Envelope2D extent = new Envelope2D();
+ extent.setCoords(-1000, -1000, 1000, 1000);
+ HashMap data = new HashMap(0);
+ QuadTree qt = new QuadTree(extent, 10);
+ for (int i = 0; i < N; i++) {
+ Envelope2D env = new Envelope2D();
+ Point2D center = generator1.GetRandomCoord().getXY();
+ double w = 10;
+ env.setCoords(center, w, w);
+ env.intersect(extent);
+ if (env.isEmpty())
+ continue;
+
+ int h = qt.insert(i, env);
+ data.put(new Integer(h), env);
+ }
+
+ int ecount = 0;
+ AttributeStreamOfInt32 handles = new AttributeStreamOfInt32(0);
+ QuadTree.QuadTreeIterator iter = qt.getIterator();
+
+ Iterator> pairs = data.entrySet().iterator();
+ while (pairs.hasNext()) {
+ Map.Entry entry = pairs.next();
+ iter.resetIterator((Envelope2D) entry.getValue(), 0.001);
+ boolean remove_self = false;
+ for (int h = iter.next(); h != -1; h = iter.next()) {
+ if (h != entry.getKey().intValue())
+ handles.add(h);
+ else {
+ remove_self = true;
+ }
+
+ ecount++;
+ }
+
+ for (int i = 0; i < handles.size(); i++) {
+ qt.removeElement(handles.get(i));//remove elements that were selected.
+ }
+
+ if (remove_self)
+ qt.removeElement(entry.getKey().intValue());
+ handles.resize(0);
+ }
+
+ //printf("%d %0.3f (%I64d, %f, mem %I64d)\n", N, timer.GetMilliseconds(), ecount, ecount / double(N * N), memsize);
+ }
+ }
+
+ @Test
+ public static void test2() {
+ MultiPoint multipoint = new MultiPoint();
+
+ for (int i = 0; i < 100; i++) {
+ for (int j = 0; j < 100; j++) {
+ multipoint.add(i, j);
+ }
+ }
+
+ Envelope2D extent = new Envelope2D();
+ multipoint.queryEnvelope2D(extent);
+
+ MultiPointImpl multipointImpl = (MultiPointImpl) multipoint._getImpl();
+ QuadTree quadtree = buildQuadTree_(multipointImpl);
+
+ QuadTree.QuadTreeIterator qtIter = quadtree.getIterator();
+ assertTrue(qtIter.next() == -1);
+
+ int count = 0;
+ qtIter.resetIterator(extent, 0.0);
+
+ while (qtIter.next() != -1) {
+ count++;
+ }
+
+ assertTrue(count == 10000);
+ }
+
+
+ public static Polyline makePolyline() {
+ Polyline poly = new Polyline();
+
+ // 0
+ poly.startPath(0, 40);
+ poly.lineTo(30, 0);
+
+ // 1
+ poly.startPath(20, 70);
+ poly.lineTo(45, 100);
+
+ // 2
+ poly.startPath(50, 100);
+ poly.lineTo(50, 60);
+
+ // 3
+ poly.startPath(35, 25);
+ poly.lineTo(65, 45);
+
+ // 4
+ poly.startPath(60, 10);
+ poly.lineTo(65, 35);
+
+ // 5
+ poly.startPath(60, 60);
+ poly.lineTo(100, 60);
+
+ // 6
+ poly.startPath(80, 10);
+ poly.lineTo(80, 99);
+
+ // 7
+ poly.startPath(60, 60);
+ poly.lineTo(65, 35);
+
+ return poly;
+ }
+
+ static QuadTree buildQuadTree_(MultiPathImpl multipathImpl, boolean bStoreDuplicates) {
+ Envelope2D extent = new Envelope2D();
+ multipathImpl.queryEnvelope2D(extent);
+ QuadTree quadTree = new QuadTree(extent, 8, bStoreDuplicates);
+ int hint_index = -1;
+ Envelope2D boundingbox = new Envelope2D();
+ SegmentIteratorImpl seg_iter = multipathImpl.querySegmentIterator();
+ while (seg_iter.nextPath()) {
+ while (seg_iter.hasNextSegment()) {
+ Segment segment = seg_iter.nextSegment();
+ int index = seg_iter.getStartPointIndex();
+ segment.queryEnvelope2D(boundingbox);
+ hint_index = quadTree.insert(index, boundingbox, hint_index);
+ }
+ }
+
+ return quadTree;
+ }
+
+ static QuadTree buildQuadTree_(MultiPointImpl multipointImpl) {
+ Envelope2D extent = new Envelope2D();
+ multipointImpl.queryEnvelope2D(extent);
+ QuadTree quadTree = new QuadTree(extent, 8);
+ Envelope2D boundingbox = new Envelope2D();
+ Point2D pt;
+
+ for (int i = 0; i < multipointImpl.getPointCount(); i++) {
+ pt = multipointImpl.getXY(i);
+ boundingbox.setCoords(pt.x, pt.y, pt.x, pt.y);
+ quadTree.insert(i, boundingbox, -1);
+ }
+
+ return quadTree;
+ }
+}
diff --git a/src/test/java/com/esri/core/geometry/TestRasterizedGeometry2D.java b/src/test/java/com/esri/core/geometry/TestRasterizedGeometry2D.java
new file mode 100644
index 00000000..c8c835be
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestRasterizedGeometry2D.java
@@ -0,0 +1,177 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
+
+public class TestRasterizedGeometry2D extends TestCase {
+ boolean rgHelper(RasterizedGeometry2D rg, MultiPath mp) {
+ SegmentIterator iter = mp.querySegmentIterator();
+ while (iter.nextPath()) {
+ while (iter.hasNextSegment()) {
+ Segment seg = iter.nextSegment();
+ int count = 20;
+
+ for (int i = 0; i < count; i++) {
+ double t = (1.0 * i / count);
+ Point2D pt = seg.getCoord2D(t);
+ RasterizedGeometry2D.HitType hit = rg.queryPointInGeometry(
+ pt.x, pt.y);
+ if (hit != RasterizedGeometry2D.HitType.Border)
+ return false;
+ }
+ }
+ }
+
+ if (mp.getType() != Geometry.Type.Polygon)
+ return true;
+
+ Polygon poly = (Polygon) mp;
+ Envelope2D env = new Envelope2D();
+ poly.queryEnvelope2D(env);
+ int count = 100;
+ for (int iy = 0; iy < count; iy++) {
+ double ty = 1.0 * iy / count;
+ double y = env.ymin * (1.0 - ty) + ty * env.ymax;
+ for (int ix = 0; ix < count; ix++) {
+ double tx = 1.0 * ix / count;
+ double x = env.xmin * (1.0 - tx) + tx * env.xmax;
+
+ RasterizedGeometry2D.HitType hit = rg
+ .queryPointInGeometry(x, y);
+ PolygonUtils.PiPResult res = PolygonUtils.isPointInPolygon2D(
+ poly, new Point2D(x, y), 0);
+ if (res == PolygonUtils.PiPResult.PiPInside) {
+ boolean bgood = (hit == RasterizedGeometry2D.HitType.Border || hit == RasterizedGeometry2D.HitType.Inside);
+ if (!bgood)
+ return false;
+ } else if (res == PolygonUtils.PiPResult.PiPOutside) {
+ boolean bgood = (hit == RasterizedGeometry2D.HitType.Border || hit == RasterizedGeometry2D.HitType.Outside);
+ if (!bgood)
+ return false;
+ } else {
+ boolean bgood = (hit == RasterizedGeometry2D.HitType.Border);
+ if (!bgood)
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ @Test
+ public void test() {
+ {
+ Polygon poly = new Polygon();
+ poly.startPath(10, 10);
+ poly.lineTo(100, 10);
+ poly.lineTo(100, 100);
+ poly.lineTo(10, 100);
+
+ // create using move semantics. Usually we do not use this
+ // approach.
+ RasterizedGeometry2D rg = RasterizedGeometry2D
+ .create(poly, 0, 1024);
+ //rg.dbgSaveToBitmap("c:/temp/_dbg.bmp");
+ RasterizedGeometry2D.HitType res;
+ res = rg.queryPointInGeometry(7, 10);
+ assertTrue(res == RasterizedGeometry2D.HitType.Outside);
+ res = rg.queryPointInGeometry(10, 10);
+ assertTrue(res == RasterizedGeometry2D.HitType.Border);
+ res = rg.queryPointInGeometry(50, 50);
+ assertTrue(res == RasterizedGeometry2D.HitType.Inside);
+
+ assertTrue(rgHelper(rg, poly));
+ }
+
+ {
+ Polygon poly = new Polygon();
+ // create a star (non-simple)
+ poly.startPath(1, 0);
+ poly.lineTo(5, 10);
+ poly.lineTo(9, 0);
+ poly.lineTo(0, 6);
+ poly.lineTo(10, 6);
+
+ RasterizedGeometry2D rg = RasterizedGeometry2D
+ .create(poly, 0, 1024);
+ //rg.dbgSaveToBitmap("c:/temp/_dbg.bmp");
+ RasterizedGeometry2D.HitType res;
+ res = rg.queryPointInGeometry(5, 5.5);
+ assertTrue(res == RasterizedGeometry2D.HitType.Outside);
+ res = rg.queryPointInGeometry(5, 8);
+ assertTrue(res == RasterizedGeometry2D.HitType.Inside);
+ res = rg.queryPointInGeometry(1.63, 0.77);
+ assertTrue(res == RasterizedGeometry2D.HitType.Inside);
+ res = rg.queryPointInGeometry(1, 3);
+ assertTrue(res == RasterizedGeometry2D.HitType.Outside);
+ res = rg.queryPointInGeometry(1.6, 0.1);
+ assertTrue(res == RasterizedGeometry2D.HitType.Outside);
+ assertTrue(rgHelper(rg, poly));
+ }
+
+ {
+ Polygon poly = new Polygon();
+ // create a star (non-simple)
+ poly.startPath(1, 0);
+ poly.lineTo(5, 10);
+ poly.lineTo(9, 0);
+ poly.lineTo(0, 6);
+ poly.lineTo(10, 6);
+
+ SpatialReference sr = SpatialReference.create(4326);
+ poly = (Polygon)OperatorSimplify.local().execute(poly, sr, true, null);
+ OperatorContains.local().accelerateGeometry(poly, sr, GeometryAccelerationDegree.enumMedium);
+ assertFalse(OperatorContains.local().execute(poly, new Point(5, 5.5), sr, null));
+ assertTrue(OperatorContains.local().execute(poly, new Point(5, 8), sr, null));
+ assertTrue(OperatorContains.local().execute(poly, new Point(1.63, 0.77), sr, null));
+ assertFalse(OperatorContains.local().execute(poly, new Point(1, 3), sr, null));
+ assertFalse(OperatorContains.local().execute(poly, new Point(1.6, 0.1), sr, null));
+ }
+
+ /*
+ {
+ Geometry g = OperatorFactoryLocal.loadGeometryFromEsriShapeDbg("c:/temp/_poly_final.bin");
+ RasterizedGeometry2D rg1 = RasterizedGeometry2D
+ .create(g, 0, 1024);//warmup
+ rg1 = null;
+
+ long t0 = System.nanoTime();
+ RasterizedGeometry2D rg = RasterizedGeometry2D
+ .create(g, 0, 1024 * 1024);
+ long t1 = System.nanoTime();
+ double d = (t1 - t0) / 1000000.0;
+ System.out.printf("Time to rasterize the geometry: %f", d);
+
+ rg.dbgSaveToBitmap("c:/temp/_dbg.bmp");
+ for (;;){}
+ }*/
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestRelation.java b/src/test/java/com/esri/core/geometry/TestRelation.java
similarity index 68%
rename from unittest/com/esri/core/geometry/TestRelation.java
rename to src/test/java/com/esri/core/geometry/TestRelation.java
index e02ed168..4ecbf514 100644
--- a/unittest/com/esri/core/geometry/TestRelation.java
+++ b/src/test/java/com/esri/core/geometry/TestRelation.java
@@ -1,11 +1,39 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
+import java.io.IOException;
+
import junit.framework.TestCase;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParser;
+
import org.junit.Test;
+import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
+
public class TestRelation extends TestCase {
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -17,7 +45,7 @@ protected void tearDown() throws Exception {
}
@Test
- public static void testCreation() {
+ public void testCreation() {
{
OperatorFactoryLocal projEnv = OperatorFactoryLocal.getInstance();
SpatialReference inputSR = SpatialReference.create(3857);
@@ -130,7 +158,7 @@ public static void testCreation() {
}
@Test
- public static void testOperatorDisjoint() {
+ public void testOperatorDisjoint() {
{
OperatorFactoryLocal projEnv = OperatorFactoryLocal.getInstance();
SpatialReference inputSR = SpatialReference.create(3857);
@@ -189,7 +217,7 @@ public static void testOperatorDisjoint() {
}
@Test
- public static void testTouchPointLineCR183227() {// Tests CR 183227
+ public void testTouchPointLineCR183227() {// Tests CR 183227
OperatorTouches operatorTouches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
@@ -217,7 +245,7 @@ public static void testTouchPointLineCR183227() {// Tests CR 183227
}
@Test
- public static void testTouchPointLineClosed() {// Tests CR 183227
+ public void testTouchPointLineClosed() {// Tests CR 183227
OperatorTouches operatorTouches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
@@ -245,7 +273,7 @@ public static void testTouchPointLineClosed() {// Tests CR 183227
}
@Test
- public static void testTouchPolygonPolygon() {
+ public void testTouchPolygonPolygon() {
OperatorTouches operatorTouches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
@@ -268,12 +296,12 @@ public static void testTouchPolygonPolygon() {
}
@Test
- public static void testContainsFailureCR186456() {
+ public void testContainsFailureCR186456() {
{
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
String str = "{\"rings\":[[[406944.399999999,287461.450000001],[406947.750000011,287462.299999997],[406946.44999999,287467.450000001],[406943.050000005,287466.550000005],[406927.799999992,287456.849999994],[406926.949999996,287456.599999995],[406924.800000005,287455.999999998],[406924.300000007,287455.849999999],[406924.200000008,287456.099999997],[406923.450000011,287458.449999987],[406922.999999987,287459.800000008],[406922.29999999,287462.099999998],[406921.949999991,287463.449999992],[406921.449999993,287465.050000011],[406920.749999996,287466.700000004],[406919.800000001,287468.599999996],[406919.050000004,287469.99999999],[406917.800000009,287471.800000008],[406916.04999999,287473.550000001],[406915.449999993,287473.999999999],[406913.700000001,287475.449999993],[406913.300000002,287475.899999991],[406912.050000008,287477.250000011],[406913.450000002,287478.150000007],[406915.199999994,287478.650000005],[406915.999999991,287478.800000005],[406918.300000007,287479.200000003],[406920.649999997,287479.450000002],[406923.100000013,287479.550000001],[406925.750000001,287479.450000002],[406928.39999999,287479.150000003],[406929.80000001,287478.950000004],[406932.449999998,287478.350000006],[406935.099999987,287477.60000001],[406938.699999998,287476.349999989],[406939.649999994,287473.949999999],[406939.799999993,287473.949999999],[406941.249999987,287473.75],[406942.700000007,287473.250000002],[406943.100000005,287473.100000003],[406943.950000001,287472.750000004],[406944.799999998,287472.300000006],[406944.999999997,287472.200000007],[406946.099999992,287471.200000011],[406946.299999991,287470.950000012],[406948.00000001,287468.599999996],[406948.10000001,287468.399999997],[406950.100000001,287465.050000011],[406951.949999993,287461.450000001],[406952.049999993,287461.300000001],[406952.69999999,287459.900000007],[406953.249999987,287458.549999987],[406953.349999987,287458.299999988],[406953.650000012,287457.299999992],[406953.900000011,287456.349999996],[406954.00000001,287455.300000001],[406954.00000001,287454.750000003],[406953.850000011,287453.750000008],[406953.550000012,287452.900000011],[406953.299999987,287452.299999988],[406954.500000008,287450.299999996],[406954.00000001,287449.000000002],[406953.399999987,287447.950000006],[406953.199999988,287447.550000008],[406952.69999999,287446.850000011],[406952.149999992,287446.099999988],[406951.499999995,287445.499999991],[406951.149999996,287445.249999992],[406950.449999999,287444.849999994],[406949.600000003,287444.599999995],[406949.350000004,287444.549999995],[406948.250000009,287444.499999995],[406947.149999987,287444.699999994],[406946.849999989,287444.749999994],[406945.899999993,287444.949999993],[406944.999999997,287445.349999991],[406944.499999999,287445.64999999],[406943.650000003,287446.349999987],[406942.900000006,287447.10000001],[406942.500000008,287447.800000007],[406942.00000001,287448.700000003],[406941.600000011,287449.599999999],[406941.350000013,287450.849999994],[406941.350000013,287451.84999999],[406941.450000012,287452.850000012],[406941.750000011,287453.850000007],[406941.800000011,287454.000000007],[406942.150000009,287454.850000003],[406942.650000007,287455.6],[406943.150000005,287456.299999997],[406944.499999999,287457.299999992],[406944.899999997,287457.599999991],[406945.299999995,287457.949999989],[406944.399999999,287461.450000001],[406941.750000011,287461.999999998],[406944.399999999,287461.450000001]],[[406944.399999999,287461.450000001],[406947.750000011,287462.299999997],[406946.44999999,287467.450000001],[406943.050000005,287466.550000005],[406927.799999992,287456.849999994],[406944.399999999,287461.450000001]]]}";
- MapGeometry mg = importFromJson(str);
+ MapGeometry mg = TestCommonMethods.fromJson(str);
boolean res = op.execute((mg.getGeometry()), (mg.getGeometry()),
null, null);
assertTrue(res);
@@ -281,14 +309,14 @@ public static void testContainsFailureCR186456() {
}
@Test
- public static void testWithin() {
+ public void testWithin() {
{
OperatorWithin op = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[0,0],[0,0],[0,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"x\":100,\"y\":100}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
@@ -303,9 +331,9 @@ public static void testWithin() {
OperatorWithin op = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[100,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"rings\":[[[10,10],[10,100],[100,100],[100,10]]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
@@ -319,9 +347,9 @@ public static void testWithin() {
OperatorWithin op = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
String str1 = "{\"points\":[[0,0],[0,200],[200,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(res);
@@ -334,9 +362,9 @@ public static void testWithin() {
OperatorWithin op = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
String str1 = "{\"points\":[[0,0],[0,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(res);
@@ -349,9 +377,9 @@ public static void testWithin() {
OperatorWithin op = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
String str1 = "{\"points\":[[0,0],[0,200],[200,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200], [1, 1]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(!res);
@@ -362,14 +390,14 @@ public static void testWithin() {
}
@Test
- public static void testContains() {
+ public void testContains() {
{
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[0,0],[0,0],[0,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"x\":100,\"y\":100}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
@@ -383,9 +411,9 @@ public static void testContains() {
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[0,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"rings\":[[[10,10],[10,100],[100,100],[10,10]]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
@@ -399,9 +427,9 @@ public static void testContains() {
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
String str1 = "{\"points\":[[0,0],[0,200],[200,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(!res);
@@ -414,9 +442,9 @@ public static void testContains() {
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
String str1 = "{\"points\":[[0,0],[0,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(res);
@@ -429,9 +457,9 @@ public static void testContains() {
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
String str1 = "{\"points\":[[0,0],[0,200],[200,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200], [1, 1]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(!res);
@@ -442,7 +470,7 @@ public static void testContains() {
}
@Test
- public static void testOverlaps() {
+ public void testOverlaps() {
{// empty polygon
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
@@ -458,9 +486,9 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[0,0],[0,0],[0,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"x\":100,\"y\":100}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
@@ -473,8 +501,8 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[0,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
- MapGeometry mg2 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str1);
Transformation2D trans = new Transformation2D();
trans.setShift(300, 0);
mg2.getGeometry().applyTransformation(trans);
@@ -489,8 +517,8 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[0,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
- MapGeometry mg2 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str1);
Transformation2D trans = new Transformation2D();
trans.setShift(30, 0);
mg2.getGeometry().applyTransformation(trans);
@@ -505,8 +533,8 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"rings\":[[[0,0],[0,200],[200,200],[200,0],[0,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
- MapGeometry mg2 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str1);
Transformation2D trans = new Transformation2D();
trans.setShift(0, 0);
mg2.getGeometry().applyTransformation(trans);
@@ -522,8 +550,8 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"paths\":[[[0,0],[100,0],[200,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
- MapGeometry mg2 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str1);
Transformation2D trans = new Transformation2D();
trans.setShift(0, 0);
mg2.getGeometry().applyTransformation(trans);
@@ -539,8 +567,8 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"paths\":[[[0,0],[100,0],[200,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
- MapGeometry mg2 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str1);
Transformation2D trans = new Transformation2D();
trans.setShift(10, 0);
mg2.getGeometry().applyTransformation(trans);
@@ -556,8 +584,8 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"paths\":[[[0,0],[100,0],[200,0]]]}";
- MapGeometry mg1 = importFromJson(str1);
- MapGeometry mg2 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str1);
Transformation2D trans = new Transformation2D();
trans.setShift(200, 0);
mg2.getGeometry().applyTransformation(trans);
@@ -573,8 +601,8 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"points\":[[0,0],[0,200],[200,200],[200,0]]}";
- MapGeometry mg1 = importFromJson(str1);
- MapGeometry mg2 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str1);
Transformation2D trans = new Transformation2D();
trans.setShift(0, 0);
mg2.getGeometry().applyTransformation(trans);
@@ -589,9 +617,9 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"points\":[[0,0],[0,200],[200,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(!res);
@@ -603,9 +631,9 @@ public static void testOverlaps() {
OperatorOverlaps op = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
String str1 = "{\"points\":[[0,0],[0,200],[200,200]]}";
- MapGeometry mg1 = importFromJson(str1);
+ MapGeometry mg1 = TestCommonMethods.fromJson(str1);
String str2 = "{\"points\":[[0,0],[0,200], [0,2]]}";
- MapGeometry mg2 = importFromJson(str2);
+ MapGeometry mg2 = TestCommonMethods.fromJson(str2);
boolean res = op.execute((mg2.getGeometry()), (mg1.getGeometry()),
null, null);
assertTrue(res);
@@ -616,7 +644,7 @@ public static void testOverlaps() {
}
@Test
- public static void testPolygonPolygonEquals() {
+ public void testPolygonPolygonEquals() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
SpatialReference sr = SpatialReference.create(102100);
@@ -626,14 +654,21 @@ public static void testPolygonPolygonEquals() {
// Polygon1 and Polygon2 are topologically equal, but have differing
// number of vertices
- String str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[0,5],[0,7],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
+ String str1 = "{\"rings\":[[[0,0],[0,5],[0,7],[0,10],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"rings\":[[[0,10],[10,10],[10,0],[0,0],[0,10]],[[9,1],[9,6],[9,9],[1,9],[1,1],[1,1],[9,1]]]}";
- Polygon polygon1 = (Polygon) importFromJson(str1).getGeometry();
- Polygon polygon2 = (Polygon) importFromJson(str2).getGeometry();
+ Polygon polygon1 = (Polygon) TestCommonMethods.fromJson(str1)
+ .getGeometry();
+ Polygon polygon2 = (Polygon) TestCommonMethods.fromJson(str2)
+ .getGeometry();
// wiggleGeometry(polygon1, tolerance, 1982);
// wiggleGeometry(polygon2, tolerance, 511);
+ equals.accelerateGeometry(polygon1, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
+ equals.accelerateGeometry(polygon2, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
+
boolean res = equals.execute(polygon1, polygon2, sr, null);
assertTrue(res);
equals.execute(polygon2, polygon1, sr, null);
@@ -643,8 +678,8 @@ public static void testPolygonPolygonEquals() {
// a hole.
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[0,10],[10,10],[5,10],[10,10],[10,0],[0,0],[0,10]]]}";
- polygon1 = (Polygon) importFromJson(str1).getGeometry();
- polygon2 = (Polygon) importFromJson(str2).getGeometry();
+ polygon1 = (Polygon) TestCommonMethods.fromJson(str1).getGeometry();
+ polygon2 = (Polygon) TestCommonMethods.fromJson(str2).getGeometry();
res = equals.execute(polygon1, polygon2, sr, null);
assertTrue(!res);
@@ -655,8 +690,8 @@ public static void testPolygonPolygonEquals() {
str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]]]}";
str2 = "{\"rings\":[[[0,10],[10,10],[10,0],[0,0],[0,10]]]}";
- polygon1 = (Polygon) importFromJson(str1).getGeometry();
- polygon2 = (Polygon) importFromJson(str2).getGeometry();
+ polygon1 = (Polygon) TestCommonMethods.fromJson(str1).getGeometry();
+ polygon2 = (Polygon) TestCommonMethods.fromJson(str2).getGeometry();
res = equals.execute(polygon1, polygon2, sr, null);
assertTrue(res);
@@ -667,17 +702,28 @@ public static void testPolygonPolygonEquals() {
str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]]]}";
str2 = "{\"rings\":[[[0,0],[10,0],[10,10],[0,10],[0,0]]]}";
- polygon1 = (Polygon) importFromJson(str1).getGeometry();
- polygon2 = (Polygon) importFromJson(str2).getGeometry();
+ polygon1 = (Polygon) TestCommonMethods.fromJson(str1).getGeometry();
+ polygon2 = (Polygon) TestCommonMethods.fromJson(str2).getGeometry();
res = equals.execute(polygon1, polygon2, sr, null);
- assertTrue(res);
+ assertTrue(!res);
res = equals.execute(polygon2, polygon1, sr, null);
- assertTrue(res);
+ assertTrue(!res);
+
+ // The rings are equal but first polygon has two rings stacked
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[0,10],[10,10],[10,0],[0,0],[0,10]]]}";
+ str2 = "{\"rings\":[[[0,10],[10,10],[10,0],[0,0],[0,10]]]}";
+ polygon1 = (Polygon) TestCommonMethods.fromJson(str1).getGeometry();
+ polygon2 = (Polygon) TestCommonMethods.fromJson(str2).getGeometry();
+
+ res = equals.execute(polygon1, polygon2, sr, null);
+ assertTrue(!res);
+ res = equals.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
}
@Test
- public static void testMultiPointMultiPointEquals() {
+ public void testMultiPointMultiPointEquals() {
OperatorEquals equals = (OperatorEquals) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals);
SpatialReference sr = SpatialReference.create(102100);
@@ -718,7 +764,7 @@ public static void testMultiPointMultiPointEquals() {
}
@Test
- public static void testMultiPointPointEquals() {
+ public void testMultiPointPointEquals() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
@@ -760,7 +806,7 @@ public static void testMultiPointPointEquals() {
}
@Test
- public static void testPointPointEquals() {
+ public void testPointPointEquals() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
@@ -823,7 +869,7 @@ public static void testPointPointEquals() {
}
@Test
- public static void testPolygonPolygonDisjoint() {
+ public void testPolygonPolygonDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
SpatialReference sr = SpatialReference.create(102100);
@@ -835,8 +881,10 @@ public static void testPolygonPolygonDisjoint() {
String str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"rings\":[[[0,10],[10,10],[10,0],[0,0],[0,10]],[[9,1],[9,6],[9,9],[1,9],[1,1],[1,1],[9,1]]]}";
- Polygon polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- Polygon polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ Polygon polygon1 = (Polygon) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polygon polygon2 = (Polygon) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
boolean res = disjoint.execute(polygon1, polygon2, sr, null);
assertTrue(!res);
@@ -847,8 +895,8 @@ public static void testPolygonPolygonDisjoint() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[10,10],[10,15],[15,15],[15,10],[10,10]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -861,8 +909,8 @@ public static void testPolygonPolygonDisjoint() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[10,0],[10,10],[15,10],[15,0],[10,0]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -875,8 +923,8 @@ public static void testPolygonPolygonDisjoint() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[8,2],[2,2]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
res = disjoint.execute(polygon1, polygon2, sr, null);
assertTrue(res);
@@ -887,17 +935,68 @@ public static void testPolygonPolygonDisjoint() {
str1 = "{\"rings\":[[[0,0],[0,5],[5,5],[5,0]],[[10,0],[10,10],[20,10],[20,0]]]}";
str2 = "{\"rings\":[[[0,-10],[0,-5],[5,-5],[5,-10]],[[11,1],[11,9],[19,9],[19,1]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
res = disjoint.execute(polygon1, polygon2, sr, null);
assertTrue(!res);
res = disjoint.execute(polygon2, polygon1, sr, null);
assertTrue(!res);
+
+ polygon1 = (Polygon)OperatorDensifyByLength.local().execute(polygon1, 0.5, null);
+ disjoint.accelerateGeometry(polygon1, sr, GeometryAccelerationDegree.enumHot);
+ res = disjoint.execute(polygon1, polygon2, sr, null);
+ assertTrue(!res);
+ res = disjoint.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ polygon1.reverseAllPaths();
+ polygon2.reverseAllPaths();
+ res = disjoint.execute(polygon1, polygon2, sr, null);
+ assertTrue(!res);
+ res = disjoint.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ // Polygon1 contains polygon2, but polygon2 is counterclockwise.
+ str1 = "{\"rings\":[[[0,0],[10,0],[10,10],[0,10],[0,0]],[[11,0],[11,10],[21,10],[21,0],[11,0]]]}";
+ str2 = "{\"rings\":[[[2,2],[8,2],[8,8],[2,8],[2,2]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+
+
+ res = disjoint.execute(polygon1, polygon2, sr, null);
+ assertTrue(!res);
+ res = disjoint.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ polygon1 = (Polygon)OperatorDensifyByLength.local().execute(polygon1, 0.5, null);
+ disjoint.accelerateGeometry(polygon1, sr, GeometryAccelerationDegree.enumHot);
+ res = disjoint.execute(polygon1, polygon2, sr, null);
+ assertTrue(!res);
+ res = disjoint.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[0,20],[0,30],[10,30],[10,20],[0,20]],[[20,20],[20,30],[30,30],[30,20],[20,20]],[[20,0],[20,10],[30,10],[30,0],[20,0]]]}";
+ str2 = "{\"rings\":[[[14,14],[14,16],[16,16],[16,14],[14,14]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+
+
+ res = disjoint.execute(polygon1, polygon2, sr, null);
+ assertTrue(res);
+ res = disjoint.execute(polygon2, polygon1, sr, null);
+ assertTrue(res);
+
+ polygon1 = (Polygon)OperatorDensifyByLength.local().execute(polygon1, 0.5, null);
+ disjoint.accelerateGeometry(polygon1, sr, GeometryAccelerationDegree.enumHot);
+ res = disjoint.execute(polygon1, polygon2, sr, null);
+ assertTrue(res);
+ res = disjoint.execute(polygon2, polygon1, sr, null);
+ assertTrue(res);
}
@Test
- public static void testPolylinePolylineDisjoint() {
+ public void testPolylinePolylineDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
SpatialReference sr = SpatialReference.create(102100);
@@ -908,8 +1007,10 @@ public static void testPolylinePolylineDisjoint() {
String str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"paths\":[[[10,10],[10,15],[15,15],[15,10],[10,10]]]}";
- Polyline polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- Polyline polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ Polyline polyline1 = (Polyline) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polyline polyline2 = (Polyline) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
wiggleGeometry(polyline1, tolerance, 1982);
wiggleGeometry(polyline2, tolerance, 511);
@@ -922,8 +1023,8 @@ public static void testPolylinePolylineDisjoint() {
str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[10,0],[10,10],[15,10],[15,0],[10,0]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polyline1, tolerance, 1982);
wiggleGeometry(polyline2, tolerance, 511);
@@ -936,8 +1037,8 @@ public static void testPolylinePolylineDisjoint() {
str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[2,2],[2,8],[8,8],[8,2],[2,2]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = disjoint.execute(polyline1, polyline2, sr, null);
assertTrue(res);
@@ -946,7 +1047,7 @@ public static void testPolylinePolylineDisjoint() {
}
@Test
- public static void testPolygonPolylineDisjoint() {
+ public void testPolygonPolylineDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
SpatialReference sr = SpatialReference.create(102100);
@@ -1007,7 +1108,7 @@ public static void testPolygonPolylineDisjoint() {
}
@Test
- public static void testPolylineMultiPointDisjoint() {
+ public void testPolylineMultiPointDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
SpatialReference sr = SpatialReference.create(102100);
@@ -1044,6 +1145,8 @@ public static void testPolylineMultiPointDisjoint() {
polyline1.lineTo(1, 0);
polyline1.lineTo(1, 1);
+ disjoint.accelerateGeometry(polyline1, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
res = disjoint.execute(polyline1, multipoint2, sr, null);
assertTrue(!res);
res = disjoint.execute(multipoint2, polyline1, sr, null);
@@ -1051,7 +1154,7 @@ public static void testPolylineMultiPointDisjoint() {
}
@Test
- public static void testPolylinePointDisjoint() {
+ public void testPolylinePointDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -1082,6 +1185,11 @@ public static void testPolylinePointDisjoint() {
point2.setXY(4, 2);
+ polyline1 = (Polyline) OperatorDensifyByLength.local().execute(
+ polyline1, 0.1, null);
+ disjoint.accelerateGeometry(polyline1, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
+
res = disjoint.execute(polyline1, point2, sr, null);
assertTrue(!res);
res = disjoint.execute(point2, polyline1, sr, null);
@@ -1105,7 +1213,7 @@ public static void testPolylinePointDisjoint() {
}
@Test
- public static void testMultiPointMultiPointDisjoint() {
+ public void testMultiPointMultiPointDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
SpatialReference sr = SpatialReference.create(102100);
@@ -1147,7 +1255,7 @@ public static void testMultiPointMultiPointDisjoint() {
}
@Test
- public static void testMultiPointPointDisjoint() {
+ public void testMultiPointPointDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -1195,7 +1303,7 @@ public static void testMultiPointPointDisjoint() {
}
@Test
- public static void testPolygonMultiPointDisjoint() {
+ public void testPolygonMultiPointDisjoint() {
OperatorDisjoint disjoint = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
SpatialReference sr = SpatialReference.create(102100);
@@ -1244,7 +1352,7 @@ public static void testPolygonMultiPointDisjoint() {
}
@Test
- public static void testPolygonMultiPointTouches() {
+ public void testPolygonMultiPointTouches() {
OperatorTouches touches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
SpatialReference sr = SpatialReference.create(102100);
@@ -1285,7 +1393,7 @@ public static void testPolygonMultiPointTouches() {
}
@Test
- public static void testPolygonPointTouches() {
+ public void testPolygonPointTouches() {
OperatorTouches touches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
SpatialReference sr = SpatialReference.create(102100);
@@ -1317,7 +1425,7 @@ public static void testPolygonPointTouches() {
}
@Test
- public static void testPolygonPolygonTouches() {
+ public void testPolygonPolygonTouches() {
OperatorTouches touches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
SpatialReference sr = SpatialReference.create(102100);
@@ -1328,8 +1436,10 @@ public static void testPolygonPolygonTouches() {
String str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"rings\":[[[10,10],[10,15],[15,15],[15,10],[10,10]]]}";
- Polygon polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- Polygon polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ Polygon polygon1 = (Polygon) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polygon polygon2 = (Polygon) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -1342,8 +1452,8 @@ public static void testPolygonPolygonTouches() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[10,0],[10,10],[15,10],[15,0],[10,0]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -1357,8 +1467,8 @@ public static void testPolygonPolygonTouches() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[15,5],[5,15],[15,15],[15,5]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -1371,8 +1481,8 @@ public static void testPolygonPolygonTouches() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[5,5],[5,15],[15,15],[15,5],[5,5]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
res = touches.execute(polygon1, polygon2, sr, null);
assertTrue(!res);
@@ -1397,7 +1507,7 @@ public static void testPolygonPolygonTouches() {
}
@Test
- public static void testPolygonPolylineTouches() {
+ public void testPolygonPolylineTouches() {
OperatorTouches touches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
SpatialReference sr = SpatialReference.create(102100);
@@ -1408,8 +1518,10 @@ public static void testPolygonPolylineTouches() {
String str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"paths\":[[[10,10],[10,15],[15,15],[15,10]]]}";
- Polygon polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- Polyline polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ Polygon polygon1 = (Polygon) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polyline polyline2 = (Polyline) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polyline2, tolerance, 511);
@@ -1422,8 +1534,8 @@ public static void testPolygonPolylineTouches() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[10,0],[10,10],[15,10],[15,0]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polyline2, tolerance, 511);
@@ -1435,8 +1547,8 @@ public static void testPolygonPolylineTouches() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15],[15,5]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polyline2, tolerance, 511);
@@ -1448,8 +1560,8 @@ public static void testPolygonPolylineTouches() {
str1 = "{\"rings\":[[[10,10],[10,0],[0,0],[0,10],[10,10]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polyline2, tolerance, 511);
@@ -1460,7 +1572,7 @@ public static void testPolygonPolylineTouches() {
}
@Test
- public static void testPolylinePolylineTouches() {
+ public void testPolylinePolylineTouches() {
OperatorTouches touches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
SpatialReference sr = SpatialReference.create(102100);
@@ -1471,8 +1583,10 @@ public static void testPolylinePolylineTouches() {
String str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"paths\":[[[10,10],[10,15],[15,15],[15,10]]]}";
- Polyline polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- Polyline polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ Polyline polyline1 = (Polyline) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polyline polyline2 = (Polyline) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
boolean res = touches.execute(polyline1, polyline2, sr, null);
assertTrue(res);
@@ -1483,8 +1597,8 @@ public static void testPolylinePolylineTouches() {
str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[10,0],[10,10],[15,10],[15,0],[10,0]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = touches.execute(polyline1, polyline2, sr, null);
assertTrue(!res);
@@ -1495,8 +1609,8 @@ public static void testPolylinePolylineTouches() {
str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15],[15,5]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = touches.execute(polyline1, polyline2, sr, null);
assertTrue(!res);
@@ -1508,8 +1622,8 @@ public static void testPolylinePolylineTouches() {
str1 = "{\"paths\":[[[10,10],[10,0],[0,0],[0,10],[10,10]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = touches.execute(polyline1, polyline2, sr, null);
assertTrue(!res);
@@ -1522,8 +1636,8 @@ public static void testPolylinePolylineTouches() {
str1 = "{\"paths\":[[[10,10],[10,0],[0,0],[0,10]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = touches.execute(polyline1, polyline2, sr, null);
assertTrue(res);
@@ -1533,8 +1647,8 @@ public static void testPolylinePolylineTouches() {
str1 = "{\"paths\":[[[10,10],[10,0],[0,0],[0,10]],[[1,1],[9,1],[9,9],[1,9],[6, 9]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15],[15,5]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = touches.execute(polyline1, polyline2, sr, null);
assertTrue(res);
@@ -1603,7 +1717,7 @@ public static void testPolylinePolylineTouches() {
}
@Test
- public static void testPolylineMultiPointTouches() {
+ public void testPolylineMultiPointTouches() {
OperatorTouches touches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
SpatialReference sr = SpatialReference.create(102100);
@@ -1634,6 +1748,8 @@ public static void testPolylineMultiPointTouches() {
polyline1.lineTo(1, 0);
polyline1.lineTo(1, 1);
+ touches.accelerateGeometry(polyline1, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
res = touches.execute(polyline1, multipoint2, sr, null);
assertTrue(res);
res = touches.execute(multipoint2, polyline1, sr, null);
@@ -1660,7 +1776,7 @@ public static void testPolylineMultiPointTouches() {
}
@Test
- public static void testPolylineMultiPointCrosses() {
+ public void testPolylineMultiPointCrosses() {
OperatorCrosses crosses = (OperatorCrosses) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Crosses));
SpatialReference sr = SpatialReference.create(102100);
@@ -1696,6 +1812,9 @@ public static void testPolylineMultiPointCrosses() {
res = crosses.execute(multipoint2, polyline1, sr, null);
assertTrue(!res);
+ crosses.accelerateGeometry(polyline1, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
+
multipoint2.add(1, 0);
res = crosses.execute(polyline1, multipoint2, sr, null);
assertTrue(res);
@@ -1710,7 +1829,7 @@ public static void testPolylineMultiPointCrosses() {
}
@Test
- public static void testPolylinePointTouches() {
+ public void testPolylinePointTouches() {
OperatorTouches touches = (OperatorTouches) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Touches));
SpatialReference sr = SpatialReference.create(102100);
@@ -1736,7 +1855,7 @@ public static void testPolylinePointTouches() {
}
@Test
- public static void testPolygonPolygonOverlaps() {
+ public void testPolygonPolygonOverlaps() {
OperatorOverlaps overlaps = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
SpatialReference sr = SpatialReference.create(102100);
@@ -1747,8 +1866,10 @@ public static void testPolygonPolygonOverlaps() {
String str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"rings\":[[[10,10],[10,15],[15,15],[15,10],[10,10]]]}";
- Polygon polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- Polygon polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ Polygon polygon1 = (Polygon) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polygon polygon2 = (Polygon) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -1761,8 +1882,8 @@ public static void testPolygonPolygonOverlaps() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[10,0],[10,10],[15,10],[15,0],[10,0]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -1776,8 +1897,8 @@ public static void testPolygonPolygonOverlaps() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[15,5],[5,15],[15,15],[15,5]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -1790,8 +1911,8 @@ public static void testPolygonPolygonOverlaps() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[5,5],[5,15],[15,15],[15,5],[5,5]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
res = overlaps.execute(polygon1, polygon2, sr, null);
assertTrue(res);
@@ -1801,8 +1922,8 @@ public static void testPolygonPolygonOverlaps() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[4,4],[6,4],[6,6],[4,6],[4,4],[4,4]]]}";
str2 = "{\"rings\":[[[1,1],[1,9],[9,9],[9,1],[1,1]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
res = overlaps.execute(polygon1, polygon2, sr, null);
assertTrue(res);
@@ -1811,7 +1932,7 @@ public static void testPolygonPolygonOverlaps() {
}
@Test
- public static void testPolygonPolylineWithin() {
+ public void testPolygonPolylineWithin() {
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
SpatialReference sr = SpatialReference.create(102100);
@@ -1844,7 +1965,7 @@ public static void testPolygonPolylineWithin() {
}
@Test
- public static void testMultiPointMultiPointWithin() {
+ public void testMultiPointMultiPointWithin() {
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
SpatialReference sr = SpatialReference.create(102100);
@@ -1896,7 +2017,7 @@ public static void testMultiPointMultiPointWithin() {
}
@Test
- public static void testPolylinePolylineOverlaps() {
+ public void testPolylinePolylineOverlaps() {
OperatorOverlaps overlaps = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
SpatialReference sr = SpatialReference.create(102100);
@@ -1963,7 +2084,7 @@ public static void testPolylinePolylineOverlaps() {
}
@Test
- public static void testMultiPointMultiPointOverlaps() {
+ public void testMultiPointMultiPointOverlaps() {
OperatorOverlaps overlaps = (OperatorOverlaps) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Overlaps));
SpatialReference sr = SpatialReference.create(102100);
@@ -2021,7 +2142,7 @@ public static void testMultiPointMultiPointOverlaps() {
}
@Test
- public static void testPolygonPolygonWithin() {
+ public void testPolygonPolygonWithin() {
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
SpatialReference sr = SpatialReference.create(102100);
@@ -2032,8 +2153,10 @@ public static void testPolygonPolygonWithin() {
String str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"rings\":[[[-1,-1],[-1,11],[11,11],[11,-1],[-1,-1]]]}";
- Polygon polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- Polygon polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ Polygon polygon1 = (Polygon) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polygon polygon2 = (Polygon) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
boolean res = within.execute(polygon1, polygon2, sr, null);
assertTrue(res);
@@ -2044,8 +2167,8 @@ public static void testPolygonPolygonWithin() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[4,4],[6,4],[6,6],[4,6],[4,4],[4,4]]]}";
str2 = "{\"rings\":[[[1,1],[1,9],[9,9],[9,1],[1,1]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -2056,8 +2179,8 @@ public static void testPolygonPolygonWithin() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[-1,0],[-1,11],[11,11],[11,0],[-1,0]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
wiggleGeometry(polygon1, tolerance, 1982);
wiggleGeometry(polygon2, tolerance, 511);
@@ -2068,16 +2191,146 @@ public static void testPolygonPolygonWithin() {
str1 = "{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[8,2],[2,2]]]}";
- polygon1 = (Polygon) (importFromJson(str1).getGeometry());
- polygon2 = (Polygon) (importFromJson(str2).getGeometry());
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
res = within.execute(polygon2, polygon1, sr, null);
assertTrue(!res);
+ str1 = "{\"rings\":[[[0,0],[10,0],[10,10],[0,10]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[8,2],[2,2],[8,2],[8,8],[2,8],[2,2]]]}";
+
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0]],[[12,8],[12,10],[18,10],[18,8],[12,8]]]}";
+ str2 = "{\"paths\":[[[2,2],[2,8],[8,8],[8,2]],[[12,2],[12,4],[18,4],[18,2]]]}";
+
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ Polyline polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
+
+ res = within.execute(polyline2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[4,4],[6,4],[6,6],[4,6],[4,4]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[8,2],[2,2],[2,8],[8,8],[8,2],[2,2]]]}";
+
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(res);
+
+ // Same as above, but winding fill rule
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[4,4],[6,4],[6,6],[4,6],[4,4]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[8,2],[2,2],[2,8],[8,8],[8,2],[2,2]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+ polygon1.setFillRule(Polygon.FillRule.enumFillRuleWinding);
+ polygon2.setFillRule(Polygon.FillRule.enumFillRuleWinding);
+
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]]]}";
+ str2 = "{\"paths\":[[[2,2],[2,2]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polyline2, polygon1, sr, null);
+ assertTrue(res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[11,11],[11,20],[20,20],[20,11],[11,11]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[15,15],[8,8],[8,2],[2,2]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[10,10],[10,20],[20,20],[20,10],[10,10]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[15,15],[8,8],[8,2],[2,2]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]]]}";
+ str2 = "{\"rings\":[[[9.9999999925,4],[9.9999999925,6],[10.0000000075,6],[10.0000000075,4],[9.9999999925,4]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ res = OperatorOverlaps.local().execute(polygon1, polygon2, sr, null);
+ assertTrue(!res);
+
+ res = OperatorTouches.local().execute(polygon1, polygon2, sr, null);
+ assertTrue(res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[10,10],[10,20],[20,20],[20,10],[10,10]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,8],[8,8],[15,15],[8,8],[8,2],[2,2]],[[15,5],[15,5],[15,5]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,2],[2,2]],[[3,3],[3,3],[3,3]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]]]}";
+ str2 = "{\"rings\":[[[2,2],[2,2],[2,2],[2,2]],[[3,3],[3,3],[3,3],[3,3]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polygon2 = (Polygon) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polygon2, polygon1, sr, null);
+ assertTrue(res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]]]}";
+ str2 = "{\"paths\":[[[2,2],[2,2]],[[3,3],[3,3]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polyline2, polygon1, sr, null);
+ assertTrue(res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[10,10],[10,20],[20,20],[20,10],[10,10]]]}";
+ str2 = "{\"paths\":[[[2,2],[2,8]],[[15,5],[15,5]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polyline2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[10,10],[10,20],[20,20],[20,10],[10,10]]]}";
+ str2 = "{\"paths\":[[[2,2],[2,8]],[[15,5],[15,5],[15,5],[15,5]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polyline2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[10,10],[10,20],[20,20],[20,10],[10,10]]]}";
+ str2 = "{\"paths\":[[[2,2],[2,2]],[[15,5],[15,6]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polyline2, polygon1, sr, null);
+ assertTrue(!res);
+
+ str1 = "{\"rings\":[[[0,0],[0,10],[10,10],[10,0],[0,0]],[[10,10],[10,20],[20,20],[20,10],[10,10]]]}";
+ str2 = "{\"paths\":[[[2,2],[2,2],[2,2],[2,2]],[[15,5],[15,6]]]}";
+ polygon1 = (Polygon) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
+ res = within.execute(polyline2, polygon1, sr, null);
+ assertTrue(!res);
}
@Test
- public static void testPolylinePolylineWithin() {
+ public void testPolylinePolylineWithin() {
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -2145,7 +2398,7 @@ public static void testPolylinePolylineWithin() {
}
@Test
- public static void testPolylineMultiPointWithin() {
+ public void testPolylineMultiPointWithin() {
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
SpatialReference sr = SpatialReference.create(102100);
@@ -2193,7 +2446,7 @@ public static void testPolylineMultiPointWithin() {
}
@Test
- public static void testPolygonMultiPointWithin() {
+ public void testPolygonMultiPointWithin() {
OperatorWithin within = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
SpatialReference sr = SpatialReference.create(102100);
@@ -2224,7 +2477,7 @@ public static void testPolygonMultiPointWithin() {
}
@Test
- public static void testPolygonPolylineCrosses() {
+ public void testPolygonPolylineCrosses() {
OperatorCrosses crosses = (OperatorCrosses) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Crosses));
SpatialReference sr = SpatialReference.create(102100);
@@ -2278,7 +2531,7 @@ public static void testPolygonPolylineCrosses() {
}
@Test
- public static void testPolylinePolylineCrosses() {
+ public void testPolylinePolylineCrosses() {
OperatorCrosses crosses = (OperatorCrosses) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Crosses));
SpatialReference sr = SpatialReference.create(102100);
@@ -2289,8 +2542,10 @@ public static void testPolylinePolylineCrosses() {
String str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
String str2 = "{\"paths\":[[[10,10],[10,15],[15,15],[15,10]]]}";
- Polyline polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- Polyline polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ Polyline polyline1 = (Polyline) (TestCommonMethods.fromJson(str1)
+ .getGeometry());
+ Polyline polyline2 = (Polyline) (TestCommonMethods.fromJson(str2)
+ .getGeometry());
boolean res = crosses.execute(polyline1, polyline2, sr, null);
assertTrue(!res);
@@ -2301,8 +2556,8 @@ public static void testPolylinePolylineCrosses() {
str1 = "{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15],[15,5]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = crosses.execute(polyline1, polyline2, sr, null);
assertTrue(res);
@@ -2314,8 +2569,8 @@ public static void testPolylinePolylineCrosses() {
str1 = "{\"paths\":[[[10,10],[10,0],[0,0],[0,10],[10,10]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
;
res = crosses.execute(polyline1, polyline2, sr, null);
@@ -2329,8 +2584,8 @@ public static void testPolylinePolylineCrosses() {
str1 = "{\"paths\":[[[10,10],[10,0],[0,0],[0,10]],[[1,1],[9,1],[9,9],[1,9],[1,1],[1,1]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = crosses.execute(polyline1, polyline2, sr, null);
assertTrue(!res);
@@ -2340,8 +2595,8 @@ public static void testPolylinePolylineCrosses() {
str1 = "{\"paths\":[[[10,11],[10,0],[0,0],[0,10]],[[1,1],[9,1],[9,9],[1,9],[6, 9]]]}";
str2 = "{\"paths\":[[[15,5],[5,15],[15,15],[15,5]]]}";
- polyline1 = (Polyline) (importFromJson(str1).getGeometry());
- polyline2 = (Polyline) (importFromJson(str2).getGeometry());
+ polyline1 = (Polyline) (TestCommonMethods.fromJson(str1).getGeometry());
+ polyline2 = (Polyline) (TestCommonMethods.fromJson(str2).getGeometry());
res = crosses.execute(polyline1, polyline2, sr, null);
assertTrue(res);
@@ -2366,7 +2621,7 @@ public static void testPolylinePolylineCrosses() {
}
@Test
- public static void testPolygonEnvelope() {
+ public void testPolygonEnvelope() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -2387,18 +2642,20 @@ public static void testPolygonEnvelope() {
SpatialReference sr = SpatialReference.create(4326);
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(equals.execute(envelope, densified, sr, null)); // they
- // cover
- // the
- // same
- // space
+ // cover
+ // the
+ // same
+ // space
assertTrue(contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2407,22 +2664,24 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // the
- // polygon
- // contains
- // the
- // envelope,
- // but
- // they
- // aren't
- // equal
+ // polygon
+ // contains
+ // the
+ // envelope,
+ // but
+ // they
+ // aren't
+ // equal
assertTrue(contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2431,23 +2690,25 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // the
- // envelope
- // sticks
- // outside
- // of
- // the
- // polygon
- // but
- // they
- // intersect
+ // envelope
+ // sticks
+ // outside
+ // of
+ // the
+ // polygon
+ // but
+ // they
+ // intersect
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2456,25 +2717,27 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":15,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":15,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // the
- // envelope
- // sticks
- // outside
- // of
- // the
- // polygon
- // but
- // they
- // intersect
- // and
- // overlap
+ // envelope
+ // sticks
+ // outside
+ // of
+ // the
+ // polygon
+ // but
+ // they
+ // intersect
+ // and
+ // overlap
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2483,23 +2746,25 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":15,\"ymax\":5}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":15,\"ymax\":5}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // the
- // envelope
- // rides
- // the
- // side
- // of
- // the
- // polygon
- // (they
- // touch)
+ // envelope
+ // rides
+ // the
+ // side
+ // of
+ // the
+ // polygon
+ // (they
+ // touch)
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
@@ -2508,20 +2773,22 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(contains.execute(densified, envelope, sr, null)); // polygon
- // and
- // envelope
- // cover
- // the
- // same
- // space
+ // and
+ // envelope
+ // cover
+ // the
+ // same
+ // space
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2529,24 +2796,26 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // envelope
- // sticks
- // outside
- // of
- // polygon,
- // but
- // the
- // envelopes
- // are
- // equal
+ // sticks
+ // outside
+ // of
+ // polygon,
+ // but
+ // the
+ // envelopes
+ // are
+ // equal
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2554,24 +2823,26 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // the
- // polygon
- // envelope
- // doesn't
- // contain
- // the
- // envelope,
- // but
- // they
- // intersect
+ // polygon
+ // envelope
+ // doesn't
+ // contain
+ // the
+ // envelope,
+ // but
+ // they
+ // intersect
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2579,25 +2850,27 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // point
- // and
- // is
- // on
- // border
- // (i.e.
- // touches)
+ // degenerate
+ // to
+ // a
+ // point
+ // and
+ // is
+ // on
+ // border
+ // (i.e.
+ // touches)
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2605,23 +2878,25 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":1,\"ymin\":1,\"xmax\":1,\"ymax\":1}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":1,\"ymin\":1,\"xmax\":1,\"ymax\":1}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // point
- // and
- // is
- // properly
- // inside
+ // degenerate
+ // to
+ // a
+ // point
+ // and
+ // is
+ // properly
+ // inside
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2629,23 +2904,25 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":-1,\"ymin\":-1,\"xmax\":-1,\"ymax\":-1}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":-1,\"ymin\":-1,\"xmax\":-1,\"ymax\":-1}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // point
- // and
- // is
- // properly
- // outside
+ // degenerate
+ // to
+ // a
+ // point
+ // and
+ // is
+ // properly
+ // outside
assertTrue(disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2653,29 +2930,31 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":1,\"ymax\":0}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":1,\"ymax\":0}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // line
- // and
- // rides
- // the
- // bottom
- // of
- // the
- // polygon
- // (no
- // interior
- // intersection)
+ // degenerate
+ // to
+ // a
+ // line
+ // and
+ // rides
+ // the
+ // bottom
+ // of
+ // the
+ // polygon
+ // (no
+ // interior
+ // intersection)
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2683,29 +2962,31 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":1,\"xmax\":1,\"ymax\":1}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":1,\"xmax\":1,\"ymax\":1}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // line,
- // touches
- // the
- // border
- // on
- // the
- // inside
- // yet
- // has
- // interior
- // intersection
+ // degenerate
+ // to
+ // a
+ // line,
+ // touches
+ // the
+ // border
+ // on
+ // the
+ // inside
+ // yet
+ // has
+ // interior
+ // intersection
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2713,25 +2994,27 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":6,\"ymax\":5}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":6,\"ymax\":5}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // line,
- // touches
- // the
- // boundary,
- // and
- // is
- // outside
+ // degenerate
+ // to
+ // a
+ // line,
+ // touches
+ // the
+ // boundary,
+ // and
+ // is
+ // outside
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2739,22 +3022,24 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":6,\"ymin\":5,\"xmax\":7,\"ymax\":5}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":6,\"ymin\":5,\"xmax\":7,\"ymax\":5}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // line,
- // and
- // is
- // outside
+ // degenerate
+ // to
+ // a
+ // line,
+ // and
+ // is
+ // outside
assertTrue(disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2762,22 +3047,24 @@ public static void testPolygonEnvelope() {
}
{
- Polygon polygon = (Polygon) (importFromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
+ Polygon polygon = (Polygon) (TestCommonMethods
+ .fromJson("{\"rings\":[[[0,0],[0,5],[0,10],[10,0],[0,0]]]}")
.getGeometry());
Polygon densified = (Polygon) (densify.execute(polygon, 1.0, null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":4,\"ymin\":5,\"xmax\":7,\"ymax\":5}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":4,\"ymin\":5,\"xmax\":7,\"ymax\":5}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null));
assertTrue(!contains.execute(densified, envelope, sr, null)); // envelope
- // degenerate
- // to
- // a
- // line,
- // and
- // crosses
- // polygon
+ // degenerate
+ // to
+ // a
+ // line,
+ // and
+ // crosses
+ // polygon
assertTrue(!disjoint.execute(densified, envelope, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
assertTrue(!overlaps.execute(envelope, densified, sr, null));
@@ -2786,7 +3073,7 @@ public static void testPolygonEnvelope() {
}
@Test
- public static void testPolylineEnvelope() {
+ public void testPolylineEnvelope() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -2808,20 +3095,22 @@ public static void testPolylineEnvelope() {
SpatialReference sr = SpatialReference.create(4326);
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
.getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // polyline
- // straddles
- // the
- // envelope
- // like
- // a hat
+ // straddles
+ // the
+ // envelope
+ // like
+ // a hat
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
@@ -2830,11 +3119,12 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[-10,0],[0,10]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[-10,0],[0,10]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -2848,11 +3138,12 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[-11,0],[1,12]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[-11,0],[1,12]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -2866,17 +3157,18 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[5,5],[6,6]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[5,5],[6,6]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // polyline
- // properly
- // inside
+ // properly
+ // inside
assertTrue(contains.execute(envelope, densified, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2885,11 +3177,12 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[5,5],[10,10]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[5,5],[10,10]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -2902,11 +3195,12 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[-5,5],[15,5]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[-5,5],[15,5]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -2920,23 +3214,24 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[5,5],[5,15]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[5,5],[5,15]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // polyline
- // slices
- // through
- // the
- // envelope
- // (interior
- // and
- // exterior
- // intersection)
+ // slices
+ // through
+ // the
+ // envelope
+ // (interior
+ // and
+ // exterior
+ // intersection)
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2945,18 +3240,19 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[5,11],[5,15]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[5,11],[5,15]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // polyline
- // outside
- // of
- // envelope
+ // outside
+ // of
+ // envelope
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2965,21 +3261,23 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
.getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // polyline
- // straddles
- // the
- // degenerate
- // envelope
- // like
- // a hat
+ // straddles
+ // the
+ // degenerate
+ // envelope
+ // like
+ // a hat
assertTrue(contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -2988,11 +3286,13 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
.getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":-5,\"xmax\":0,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":-5,\"xmax\":0,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3005,22 +3305,24 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
.getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 511);
wiggleGeometry(envelope, 0.00000001, 1982);
assertTrue(!equals.execute(envelope, densified, sr, null)); // degenerate
- // envelope
- // is at
- // the
- // end
- // point
- // of
- // polyline
+ // envelope
+ // is at
+ // the
+ // end
+ // point
+ // of
+ // polyline
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
@@ -3029,21 +3331,23 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[0,0],[0,5],[0,10],[10,10],[10,0]]]}")
.getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":5,\"xmax\":0,\"ymax\":5}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":5,\"xmax\":0,\"ymax\":5}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // degenerate
- // envelope
- // is at
- // the
- // interior
- // of
- // polyline
+ // envelope
+ // is at
+ // the
+ // interior
+ // of
+ // polyline
assertTrue(contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -3052,18 +3356,19 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[2,-2],[2,2]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[2,-2],[2,2]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // degenerate
- // envelope
- // crosses
- // polyline
+ // envelope
+ // crosses
+ // polyline
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -3072,18 +3377,19 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[2,0],[2,2]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[2,0],[2,2]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // degenerate
- // envelope
- // crosses
- // polyline
+ // envelope
+ // crosses
+ // polyline
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
@@ -3092,18 +3398,19 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[2,0],[2,2]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[2,0],[2,2]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":2,\"ymin\":0,\"xmax\":2,\"ymax\":3}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":2,\"ymin\":0,\"xmax\":2,\"ymax\":3}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // degenerate
- // envelope
- // contains
- // polyline
+ // envelope
+ // contains
+ // polyline
assertTrue(!contains.execute(densified, envelope, sr, null));
assertTrue(contains.execute(envelope, densified, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
@@ -3113,17 +3420,18 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[5,5],[6,6]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[5,5],[6,6]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":5}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":5}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, densified, sr, null)); // polyline
- // properly
- // inside
+ // properly
+ // inside
assertTrue(!contains.execute(envelope, densified, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(touches.execute(envelope, densified, sr, null));
@@ -3132,17 +3440,18 @@ public static void testPolylineEnvelope() {
}
{
- Polyline polyline = (Polyline) (importFromJson("{\"paths\":[[[5,5],[5,10]]]}")
- .getGeometry());
+ Polyline polyline = (Polyline) (TestCommonMethods
+ .fromJson("{\"paths\":[[[5,5],[5,10]]]}").getGeometry());
Polyline densified = (Polyline) (densify.execute(polyline, 1.0,
null));
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":5,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":5,\"ymax\":10}")
.getGeometry());
wiggleGeometry(densified, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(equals.execute(envelope, densified, sr, null)); // polyline
- // properly
- // inside
+ // properly
+ // inside
assertTrue(contains.execute(envelope, densified, sr, null));
assertTrue(!disjoint.execute(envelope, densified, sr, null));
assertTrue(!touches.execute(envelope, densified, sr, null));
@@ -3152,7 +3461,7 @@ public static void testPolylineEnvelope() {
}
@Test
- public static void testMultiPointEnvelope() {
+ public void testMultiPointEnvelope() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -3175,16 +3484,18 @@ public static void testMultiPointEnvelope() {
SpatialReference sr = SpatialReference.create(4326);
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,0],[0,10],[10,10],[10,0]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,0],[0,10],[10,10],[10,0]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // all
- // points
- // on
- // boundary
+ // points
+ // on
+ // boundary
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(touches.execute(envelope, multi_point, sr, null));
@@ -3193,20 +3504,22 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,0],[0,10],[10,10],[5,5]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,0],[0,10],[10,10],[5,5]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // points
- // on
- // boundary
- // and
- // one
- // point
- // in
- // interior
+ // on
+ // boundary
+ // and
+ // one
+ // point
+ // in
+ // interior
assertTrue(contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(!touches.execute(envelope, multi_point, sr, null));
@@ -3215,19 +3528,21 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,0],[0,10],[10,10],[5,5],[15,15]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,0],[0,10],[10,10],[5,5],[15,15]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // points
- // on
- // boundary,
- // one
- // interior,
- // one
- // exterior
+ // on
+ // boundary,
+ // one
+ // interior,
+ // one
+ // exterior
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(!touches.execute(envelope, multi_point, sr, null));
@@ -3236,17 +3551,19 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,0],[0,10],[10,10],[15,15]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,0],[0,10],[10,10],[15,15]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // points
- // on
- // boundary,
- // one
- // exterior
+ // on
+ // boundary,
+ // one
+ // exterior
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(touches.execute(envelope, multi_point, sr, null));
@@ -3255,15 +3572,17 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // all
- // points
- // exterior
+ // points
+ // exterior
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(disjoint.execute(envelope, multi_point, sr, null));
assertTrue(!touches.execute(envelope, multi_point, sr, null));
@@ -3272,25 +3591,27 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,0],[0,10],[10,10],[10,0]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,0],[0,10],[10,10],[10,0]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // degenerate
- // envelope
- // slices
- // through
- // some
- // points,
- // but
- // some
- // points
- // are
- // off
- // the
- // line
+ // envelope
+ // slices
+ // through
+ // some
+ // points,
+ // but
+ // some
+ // points
+ // are
+ // off
+ // the
+ // line
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(touches.execute(envelope, multi_point, sr, null));
@@ -3299,25 +3620,27 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,0],[1,10],[10,10],[10,0]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,0],[1,10],[10,10],[10,0]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // degenerate
- // envelope
- // slices
- // through
- // some
- // points,
- // but
- // some
- // points
- // are
- // off
- // the
- // line
+ // envelope
+ // slices
+ // through
+ // some
+ // points,
+ // but
+ // some
+ // points
+ // are
+ // off
+ // the
+ // line
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(!touches.execute(envelope, multi_point, sr, null));
@@ -3326,29 +3649,30 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,10],[10,10]]}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,10],[10,10]]}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // degenerate
- // envelopes
- // slices
- // through
- // all
- // the
- // points,
- // and
- // they
- // are
- // at
- // the
- // end
- // points
- // of
- // the
- // line
+ // envelopes
+ // slices
+ // through
+ // all
+ // the
+ // points,
+ // and
+ // they
+ // are
+ // at
+ // the
+ // end
+ // points
+ // of
+ // the
+ // line
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(touches.execute(envelope, multi_point, sr, null));
@@ -3357,28 +3681,29 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[1,10],[9,10]]}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[1,10],[9,10]]}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // degenerate
- // envelopes
- // slices
- // through
- // all
- // the
- // points,
- // and
- // they
- // are
- // in
- // the
- // interior
- // of
- // the
- // line
+ // envelopes
+ // slices
+ // through
+ // all
+ // the
+ // points,
+ // and
+ // they
+ // are
+ // in
+ // the
+ // interior
+ // of
+ // the
+ // line
assertTrue(contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
assertTrue(!touches.execute(envelope, multi_point, sr, null));
@@ -3387,15 +3712,17 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // all
- // points
- // exterior
+ // points
+ // exterior
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(disjoint.execute(envelope, multi_point, sr, null));
assertTrue(!touches.execute(envelope, multi_point, sr, null));
@@ -3404,15 +3731,17 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":10,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":10,\"ymin\":10,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // all
- // points
- // exterior
+ // points
+ // exterior
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(disjoint.execute(envelope, multi_point, sr, null));
assertTrue(!touches.execute(envelope, multi_point, sr, null));
@@ -3421,15 +3750,17 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,-1],[0,11],[11,11],[15,15]]}")
.getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":11,\"ymax\":11}")
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":11,\"ymax\":11}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(!equals.execute(envelope, multi_point, sr, null)); // all
- // points
- // exterior
+ // points
+ // exterior
assertTrue(!contains.execute(multi_point, envelope, sr, null));
assertTrue(!contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
@@ -3439,15 +3770,16 @@ public static void testMultiPointEnvelope() {
}
{
- MultiPoint multi_point = (MultiPoint) (importFromJson("{\"points\":[[0,-1],[0,-1]]}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":-1,\"xmax\":0,\"ymax\":-1}")
+ MultiPoint multi_point = (MultiPoint) (TestCommonMethods
+ .fromJson("{\"points\":[[0,-1],[0,-1]]}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":-1,\"xmax\":0,\"ymax\":-1}")
.getGeometry());
wiggleGeometry(multi_point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
assertTrue(equals.execute(envelope, multi_point, sr, null)); // all
- // points
- // exterior
+ // points
+ // exterior
assertTrue(contains.execute(multi_point, envelope, sr, null));
assertTrue(contains.execute(envelope, multi_point, sr, null));
assertTrue(!disjoint.execute(envelope, multi_point, sr, null));
@@ -3458,7 +3790,7 @@ public static void testMultiPointEnvelope() {
}
@Test
- public static void testPointEnvelope() {
+ public void testPointEnvelope() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -3477,9 +3809,10 @@ public static void testPointEnvelope() {
SpatialReference sr = SpatialReference.create(4326);
{
- Point point = (Point) (importFromJson("{\"x\":5,\"y\":6}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Point point = (Point) (TestCommonMethods
+ .fromJson("{\"x\":5,\"y\":6}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3493,9 +3826,10 @@ public static void testPointEnvelope() {
}
{
- Point point = (Point) (importFromJson("{\"x\":0,\"y\":10}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Point point = (Point) (TestCommonMethods
+ .fromJson("{\"x\":0,\"y\":10}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3509,9 +3843,10 @@ public static void testPointEnvelope() {
}
{
- Point point = (Point) (importFromJson("{\"x\":0,\"y\":11}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Point point = (Point) (TestCommonMethods
+ .fromJson("{\"x\":0,\"y\":11}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3525,9 +3860,10 @@ public static void testPointEnvelope() {
}
{
- Point point = (Point) (importFromJson("{\"x\":0,\"y\":0}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Point point = (Point) (TestCommonMethods
+ .fromJson("{\"x\":0,\"y\":0}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3541,9 +3877,10 @@ public static void testPointEnvelope() {
}
{
- Point point = (Point) (importFromJson("{\"x\":5,\"y\":0}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Point point = (Point) (TestCommonMethods
+ .fromJson("{\"x\":5,\"y\":0}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3557,9 +3894,10 @@ public static void testPointEnvelope() {
}
{
- Point point = (Point) (importFromJson("{\"x\":11,\"y\":0}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Point point = (Point) (TestCommonMethods
+ .fromJson("{\"x\":11,\"y\":0}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3573,9 +3911,10 @@ public static void testPointEnvelope() {
}
{
- Point point = (Point) (importFromJson("{\"x\":0,\"y\":0}")
- .getGeometry());
- Envelope envelope = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
+ Point point = (Point) (TestCommonMethods
+ .fromJson("{\"x\":0,\"y\":0}").getGeometry());
+ Envelope envelope = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
.getGeometry());
wiggleGeometry(point, 0.00000001, 1982);
wiggleGeometry(envelope, 0.00000001, 511);
@@ -3590,7 +3929,7 @@ public static void testPointEnvelope() {
}
@Test
- public static void testEnvelopeEnvelope() {
+ public void testEnvelopeEnvelope() {
OperatorEquals equals = (OperatorEquals) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals));
OperatorContains contains = (OperatorContains) (OperatorFactoryLocal
@@ -3609,9 +3948,11 @@ public static void testEnvelopeEnvelope() {
SpatialReference sr = SpatialReference.create(4326);
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3628,9 +3969,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3646,9 +3989,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":15,\"ymax\":15}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":15,\"ymax\":15}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3664,9 +4009,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3682,9 +4029,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3700,9 +4049,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":20}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":10,\"xmax\":10,\"ymax\":20}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3718,9 +4069,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3736,9 +4089,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3754,9 +4109,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":-5,\"ymin\":5,\"xmax\":0,\"ymax\":5}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":-5,\"ymin\":5,\"xmax\":0,\"ymax\":5}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3772,9 +4129,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":-5,\"ymin\":5,\"xmax\":5,\"ymax\":5}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":-5,\"ymin\":5,\"xmax\":5,\"ymax\":5}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3790,9 +4149,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":3,\"ymin\":5,\"xmax\":5,\"ymax\":5}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":3,\"ymin\":5,\"xmax\":5,\"ymax\":5}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3808,9 +4169,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":3,\"ymin\":5,\"xmax\":10,\"ymax\":5}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":3,\"ymin\":5,\"xmax\":10,\"ymax\":5}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3826,9 +4189,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":-5,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":-5,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3844,9 +4209,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3862,9 +4229,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3880,9 +4249,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":15,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":-5,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":-5,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3898,9 +4269,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":-5,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":-5,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3916,9 +4289,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":-5,\"xmax\":5,\"ymax\":5}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":-5,\"xmax\":5,\"ymax\":5}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3934,9 +4309,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":10,\"ymin\":0,\"xmax\":20,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3952,9 +4329,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":5}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":5}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3971,9 +4350,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -3990,9 +4371,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -4009,9 +4392,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":5,\"ymax\":5}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":5,\"xmax\":5,\"ymax\":5}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":10}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -4028,9 +4413,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":0,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -4047,9 +4434,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":0,\"ymin\":0,\"xmax\":10,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -4066,9 +4455,11 @@ public static void testEnvelopeEnvelope() {
}
{
- Envelope env1 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
+ Envelope env1 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
.getGeometry());
- Envelope env2 = (Envelope) (importFromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
+ Envelope env2 = (Envelope) (TestCommonMethods
+ .fromJson("{\"xmin\":5,\"ymin\":0,\"xmax\":5,\"ymax\":0}")
.getGeometry());
wiggleGeometry(env1, 0.00000001, 1982);
wiggleGeometry(env2, 0.00000001, 511);
@@ -4166,7 +4557,7 @@ static void wiggleGeometry(Geometry geometry, double tolerance, int rand) {
}
@Test
- public static void testDisjointRelationFalse() {
+ public void testDisjointRelationFalse() {
{
OperatorDisjoint op = (OperatorDisjoint) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Disjoint));
@@ -4241,198 +4632,341 @@ public static void testDisjointRelationFalse() {
}
@Test
- public static void testPolylinePolylineRelate() {
- OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Relate));
- SpatialReference sr = SpatialReference.create(4326);
- boolean res;
- String scl;
+ public void testPolylinePolylineRelate() {
+ OperatorRelate op = OperatorRelate.local();
+ SpatialReference sr = SpatialReference.create(4326);
+ boolean res;
+ String scl;
- Polyline polyline1 = new Polyline();
- Polyline polyline2 = new Polyline();
+ Polyline polyline1 = new Polyline();
+ Polyline polyline2 = new Polyline();
- polyline1.startPath(0, 0);
- polyline1.lineTo(1, 1);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(1, 1);
- polyline2.startPath(1, 1);
- polyline2.lineTo(2, 0);
-
- scl = "FF1FT01T2";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
-
- scl = "****TF*T*";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
-
- scl = "****F****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
-
- scl = "**1*0*T**";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
-
- scl = "****1****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
-
- scl = "**T*001*T";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
-
- scl = "T********";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ polyline2.startPath(1, 1);
+ polyline2.lineTo(2, 0);
- scl = "F********";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "FF1FT01T2";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline1.setEmpty();
- polyline2.setEmpty();
-
- polyline1.startPath(0, 0);
- polyline1.lineTo(1, 0);
+ scl = "****TF*T*";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- polyline2.startPath(0, 0);
- polyline2.lineTo(1, 0);
+ scl = "****F****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- scl = "1FFFTFFFT";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "**1*0*T**";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- scl = "1*T*T****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "****1****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- scl = "1T**T****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "**T*001*T";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline1.setEmpty();
- polyline2.setEmpty();
+ scl = "T********";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- polyline1.startPath(0, 0);
- polyline1.lineTo(0.5, 0.5);
- polyline1.lineTo(1, 1);
+ scl = "F********";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline2.startPath(1, 0);
- polyline2.lineTo(0.5, 0.5);
- polyline2.lineTo(0, 1);
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- scl = "0F1FFTT0T";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(1, 0);
- scl = "*T*******";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ polyline2.startPath(0, 0);
+ polyline2.lineTo(1, 0);
- scl = "*F*F*****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "1FFFTFFFT";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline1.setEmpty();
- polyline2.setEmpty();
+ scl = "1*T*T****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- polyline1.startPath(0, 0);
- polyline1.lineTo(1, 0);
+ scl = "1T**T****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- polyline2.startPath(1, -1);
- polyline2.lineTo(1, 1);
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- scl = "FT1TF01TT";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(0.5, 0.5);
+ polyline1.lineTo(1, 1);
- scl = "***T*****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
- }
+ polyline2.startPath(1, 0);
+ polyline2.lineTo(0.5, 0.5);
+ polyline2.lineTo(0, 1);
- @Test
- public static void testPolygonPolylineRelate() {
- OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Relate));
- SpatialReference sr = SpatialReference.create(4326);
- boolean res;
- String scl;
+ scl = "0F1FFTT0T";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- Polygon polygon1 = new Polygon();
- Polyline polyline2 = new Polyline();
+ scl = "*T*******";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- polygon1.startPath(0, 0);
- polygon1.lineTo(0, 10);
- polygon1.lineTo(10, 10);
- polygon1.lineTo(10, 0);
+ scl = "*F*F*****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline2.startPath(-10, 0);
- polyline2.lineTo(0, 0);
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- scl = "FF2F01102";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(1, 0);
- scl = "**1*0110*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(!res);
+ polyline2.startPath(1, -1);
+ polyline2.lineTo(1, 1);
- scl = "T***T****";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "FT1TF01TT";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- scl = "FF*FT****";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "***T*****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline2.setEmpty();
- polyline2.startPath(0, 0);
- polyline2.lineTo(10, 0);
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- scl = "***1*1FF*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(0, 20);
+ polyline1.lineTo(20, 20);
+ polyline1.lineTo(20, 0);
+ polyline1.lineTo(0, 0); // has no boundary
- scl = "F**1*1FF*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
+ polyline2.startPath(3, 3);
+ polyline2.lineTo(5, 5);
+
+ op.accelerateGeometry(polyline1, sr, Geometry.GeometryAccelerationDegree.enumHot);
- scl = "0**1*1FF*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "FF1FFF102";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- scl = "F**1*1TF*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(!res);
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- polyline2.setEmpty();
- polyline2.startPath(1, 1);
- polyline2.lineTo(5, 5);
+ polyline1.startPath(4, 0);
+ polyline1.lineTo(0, 4);
+ polyline1.lineTo(4, 8);
+ polyline1.lineTo(8, 4);
- scl = "TT*******";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
+ polyline2.startPath(8, 1);
+ polyline2.lineTo(8, 2);
- scl = "1T2FF1FF*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
+ op.accelerateGeometry(polyline1, sr, GeometryAccelerationDegree.enumHot);
- scl = "1T1FF1FF*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "FF1FF0102";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline2.setEmpty();
- polyline2.startPath(5, 5);
- polyline2.lineTo(15, 5);
+ polyline1.setEmpty();
+ polyline2.setEmpty();
+ polyline1.startPath(4, 0);
+ polyline1.lineTo(0, 4);
+ polyline2.startPath(3, 2);
+ polyline2.lineTo(3, 2);
+ assertTrue(polyline2.getBoundary().isEmpty());
+
+ scl = "******0F*";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polyline2.lineTo(3, 2);
+ assertTrue(polyline2.getBoundary().isEmpty());
+
+ scl = "******0F*";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
+ scl = "******0F*";
+
+ polyline2.lineTo(3, 2);
+ assertTrue(polyline2.getBoundary().isEmpty());
+
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polyline1.setEmpty();
+ polyline2.setEmpty();
+ polyline1.startPath(3, 3);
+ polyline1.lineTo(3, 4);
+ polyline1.lineTo(3, 3);
+ polyline2.startPath(1, 1);
+ polyline2.lineTo(1, 1);
+
+ scl = "FF1FFF0F2";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
+ scl = "FF0FFF1F2";
+ res = op.execute(polyline2, polyline1, sr, scl, null);
+ assertTrue(res);
+
+ polyline1.setEmpty();
+ polyline2.setEmpty();
+ polyline1.startPath(4, 0);
+ polyline1.lineTo(0, 4);
+ polyline2.startPath(2, 2);
+ polyline2.lineTo(2, 2);
+
+ scl = "0F*******";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polyline2.lineTo(2, 2);
+
+ scl = "0F*******";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
+ scl = "0F*******";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
+ }
- scl = "1T*0F*T0T";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
+ @Test
+ public void testPolygonPolylineRelate() {
+ OperatorRelate op = OperatorRelate.local();
+ SpatialReference sr = SpatialReference.create(4326);
+ boolean res;
+ String scl;
+
+ Polygon polygon1 = new Polygon();
+ Polyline polyline2 = new Polyline();
+
+ polygon1.startPath(0, 0);
+ polygon1.lineTo(0, 10);
+ polygon1.lineTo(10, 10);
+ polygon1.lineTo(10, 0);
+
+ polyline2.startPath(-10, 0);
+ polyline2.lineTo(0, 0);
+
+ scl = "FF2F01102";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ scl = "**1*0110*";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(!res);
+
+ scl = "T***T****";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(!res);
+
+ scl = "FF2FT****";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polyline2.setEmpty();
+ polyline2.startPath(0, 0);
+ polyline2.lineTo(10, 0);
+
+ scl = "**21*1FF*";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ scl = "F*21*1FF*";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ scl = "0**1*1FF*";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(!res);
+
+ scl = "F**1*1TF*";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(!res);
+
+ polyline2.setEmpty();
+ polyline2.startPath(1, 1);
+ polyline2.lineTo(5, 5);
+
+ scl = "TT2******";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ scl = "1T2FF1FF*";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ scl = "1T1FF1FF*";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(!res);
+
+ polyline2.setEmpty();
+ polyline2.startPath(5, 5);
+ polyline2.lineTo(15, 5);
+
+ scl = "1T20F*T0T";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polygon1.setEmpty();
+ polyline2.setEmpty();
+
+ polygon1.startPath(2, 0);
+ polygon1.lineTo(0, 2);
+ polygon1.lineTo(2, 4);
+ polygon1.lineTo(4, 2);
+
+ polyline2.startPath(1, 2);
+ polyline2.lineTo(3, 2);
+
+ op.accelerateGeometry(polygon1, sr, GeometryAccelerationDegree.enumHot);
+ scl = "TTTFF****";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polyline2.setEmpty();
+ polyline2.startPath(5, 2);
+ polyline2.lineTo(7, 2);
+ scl = "FF2FFT***";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polygon1.setEmpty();
+ polyline2.setEmpty();
+ polygon1.startPath(0, 0);
+ polygon1.lineTo(0, 1);
+ polygon1.lineTo(1, 0);
+ polyline2.startPath(0, 10);
+ polyline2.lineTo(0, 9);
+ polyline2.startPath(10, 0);
+ polyline2.lineTo(9, 0);
+ polyline2.startPath(0, -10);
+ polyline2.lineTo(0, -9);
+ scl = "**2******";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
+
+ polygon1.setEmpty();
+ polyline2.setEmpty();
+ polygon1.startPath(0, 0);
+ polygon1.lineTo(0, 1);
+ polygon1.lineTo(0, 0);
+ polyline2.startPath(0, 10);
+ polyline2.lineTo(0, 9);
+ scl = "**1******";
+ res = op.execute(polygon1, polyline2, sr, scl, null);
+ assertTrue(res);
}
@Test
- public static void testPolygonPolygonRelate() {
+ public void testPolygonPolygonRelate() {
OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Relate));
SpatialReference sr = SpatialReference.create(4326);
@@ -4479,10 +5013,46 @@ public static void testPolygonPolygonRelate() {
scl = "212FF1FFT";
res = op.execute(polygon1, polygon2, sr, scl, null);
assertTrue(res);
+
+ polygon1.setEmpty();
+ polygon2.setEmpty();
+ polygon1.startPath(3, 3);
+ polygon1.lineTo(3, 4);
+ polygon1.lineTo(3, 3);
+ polygon2.startPath(1, 1);
+ polygon2.lineTo(1, 1);
+
+ scl = "FF1FFF0F2";
+ res = op.execute(polygon1, polygon2, sr, scl, null);
+ assertTrue(res);
+ scl = "FF0FFF1F2";
+ res = op.execute(polygon2, polygon1, sr, scl, null);
+ assertTrue(res);
+
+ polygon1.setEmpty();
+ polygon2.setEmpty();
+ polygon1.startPath(0, 0);
+ polygon1.lineTo(0, 100);
+ polygon1.lineTo(100, 100);
+ polygon1.lineTo(100, 0);
+ polygon2.startPath(50, 50);
+ polygon2.lineTo(50, 50);
+ polygon2.lineTo(50, 50);
+
+ op.accelerateGeometry(polygon1, sr, GeometryAccelerationDegree.enumHot);
+
+ scl = "0F2FF1FF2";
+ res = op.execute(polygon1, polygon2, sr, scl, null);
+ assertTrue(res);
+
+ polygon2.lineTo(51, 50);
+ scl = "1F2FF1FF2";
+ res = op.execute(polygon1, polygon2, sr, scl, null);
+ assertTrue(res);
}
@Test
- public static void testMultiPointPointRelate() {
+ public void testMultiPointPointRelate() {
OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Relate));
SpatialReference sr = SpatialReference.create(4326);
@@ -4506,10 +5076,19 @@ public static void testMultiPointPointRelate() {
m1.add(1, 1);
res = op.execute(m1, p2, sr, scl, null);
assertTrue(res);
+
+ m1.setEmpty();
+
+ m1.add(1, 1);
+ m1.add(2, 2);
+
+ scl = "FF0FFFTF2";
+ res = op.execute(m1, p2, sr, scl, null);
+ assertTrue(res);
}
@Test
- public static void testPointPointRelate() {
+ public void testPointPointRelate() {
OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Relate));
SpatialReference sr = SpatialReference.create(4326);
@@ -4525,10 +5104,27 @@ public static void testPointPointRelate() {
scl = "T********";
res = op.execute(p1, p2, sr, scl, null);
assertTrue(res);
+
+ p1.setXY(0, 0);
+ p2.setXY(1, 0);
+ res = op.execute(p1, p2, null, scl, null);
+ assertTrue(!res);
+
+ p1.setEmpty();
+ p2.setEmpty();
+ scl = "*********";
+ res = op.execute(p1, p2, null, scl, null);
+ assertTrue(res);
+ scl = "FFFFFFFFF";
+ res = op.execute(p1, p2, null, scl, null);
+ assertTrue(res);
+ scl = "FFFFFFFFT";
+ res = op.execute(p1, p2, null, scl, null);
+ assertTrue(!res);
}
@Test
- public static void testPolygonMultiPointRelate() {
+ public void testPolygonMultiPointRelate() {
OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Relate));
SpatialReference sr = SpatialReference.create(4326);
@@ -4569,10 +5165,46 @@ public static void testPolygonMultiPointRelate() {
scl = "TFF0F10FT";
res = op.execute(polygon1, multipoint2, sr, scl, null);
assertTrue(!res);
+
+ polygon1.setEmpty();
+ multipoint2.setEmpty();
+
+ polygon1.startPath(0, 0);
+ polygon1.lineTo(0, 20);
+ polygon1.lineTo(20, 20);
+ polygon1.lineTo(20, 0);
+
+ multipoint2.add(3, 3);
+ multipoint2.add(5, 5);
+
+ op.accelerateGeometry(polygon1, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
+
+ scl = "TF2FF****";
+ res = op.execute(polygon1, multipoint2, sr, scl, null);
+ assertTrue(res);
+
+ polygon1.setEmpty();
+ multipoint2.setEmpty();
+
+ polygon1.startPath(4, 0);
+ polygon1.lineTo(0, 4);
+ polygon1.lineTo(4, 8);
+ polygon1.lineTo(8, 4);
+
+ multipoint2.add(8, 1);
+ multipoint2.add(8, 2);
+
+ op.accelerateGeometry(polygon1, sr,
+ Geometry.GeometryAccelerationDegree.enumHot);
+
+ scl = "FF2FF10F2";
+ res = op.execute(polygon1, multipoint2, sr, scl, null);
+ assertTrue(res);
}
@Test
- public static void testPolygonPointRelate() {
+ public void testPolygonPointRelate() {
OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Relate));
SpatialReference sr = SpatialReference.create(4326);
@@ -4592,42 +5224,147 @@ public static void testPolygonPointRelate() {
scl = "FF20FTFFT";
res = op.execute(polygon, point, sr, scl, null);
assertTrue(res);
+
+ polygon.setEmpty();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 0);
+ scl = "0FFFFFFF2";
+ res = op.execute(polygon, point, sr, scl, null);
+ assertTrue(res);
+
+ polygon.setEmpty();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 1);
+ polygon.lineTo(0, 0);
+ scl = "0F1FFFFF2";
+ res = op.execute(polygon, point, sr, scl, null);
+ assertTrue(res);
+
+ point.setXY(-1, 0);
+
+ scl = "FF1FFF0F2";
+ res = op.execute(polygon, point, sr, scl, null);
+ assertTrue(res);
+
+ polygon.setEmpty();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 10);
+ polygon.lineTo(0, 0);
+ scl = "FF1FFFTFT";
+ res = op.execute(polygon, point, sr, scl, null);
+ assertTrue(res);
+
+ polygon.setEmpty();
+ polygon.startPath(0, 0);
+ polygon.lineTo(0, 0);
+ polygon.lineTo(0, 0);
+ scl = "FF0FFF0F2";
+ res = op.execute(polygon, point, sr, scl, null);
+ assertTrue(res);
}
@Test
- public static void testPolylineMultiPointRelate() {
- OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Relate));
- SpatialReference sr = SpatialReference.create(4326);
- boolean res;
- String scl;
+ public void testPolylineMultiPointRelate() {
+ OperatorRelate op = OperatorRelate.local();
+ SpatialReference sr = SpatialReference.create(4326);
+ boolean res;
+ String scl;
- Polyline polyline1 = new Polyline();
- MultiPoint multipoint2 = new MultiPoint();
+ Polyline polyline1 = new Polyline();
+ MultiPoint multipoint2 = new MultiPoint();
- polyline1.startPath(0, 0);
- polyline1.lineTo(10, 0);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(10, 0);
- multipoint2.add(0, 0);
- multipoint2.add(5, 5);
+ multipoint2.add(0, 0);
+ multipoint2.add(5, 5);
- scl = "FF10F00F2";
- res = op.execute(polyline1, multipoint2, sr, scl, null);
- assertTrue(res);
+ scl = "FF10F00F2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
- multipoint2.add(5, 0);
+ multipoint2.add(5, 0);
- scl = "0F10F00F2";
- res = op.execute(polyline1, multipoint2, sr, scl, null);
- assertTrue(res);
+ scl = "0F10F00F2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
- scl = "0F11F00F2";
- res = op.execute(polyline1, multipoint2, sr, scl, null);
- assertTrue(!res);
+ scl = "0F11F00F2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(!res);
+
+ polyline1.setEmpty();
+ multipoint2.setEmpty();
+
+ polyline1.startPath(4, 0);
+ polyline1.lineTo(0, 4);
+ polyline1.lineTo(4, 8);
+ polyline1.lineTo(8, 4);
+ polyline1.lineTo(4, 0); // has no boundary
+
+ multipoint2.add(8, 1);
+ multipoint2.add(8, 2);
+
+ op.accelerateGeometry(polyline1, sr, GeometryAccelerationDegree.enumHot);
+
+ scl = "FF1FFF0F2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
+
+ polyline1.setEmpty();
+ multipoint2.setEmpty();
+
+ polyline1.startPath(4, 0);
+ polyline1.lineTo(4, 0);
+
+ multipoint2.add(8, 1);
+ multipoint2.add(8, 2);
+
+ scl = "FF0FFF0F2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
+
+ multipoint2.add(-2, 0);
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
+
+ op.accelerateGeometry(polyline1, sr, GeometryAccelerationDegree.enumHot);
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
+
+ polyline1.setEmpty();
+ multipoint2.setEmpty();
+
+ polyline1.startPath(10, 10);
+ polyline1.lineTo(10, 10);
+ multipoint2.add(10, 10);
+
+ scl = "0FFFFFFF2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
+
+ polyline1.startPath(12, 12);
+ polyline1.lineTo(12, 12);
+
+ scl = "0F0FFFFF2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
+
+ polyline1.setEmpty();
+ multipoint2.setEmpty();
+
+ polyline1.startPath(10, 10);
+ polyline1.lineTo(10, 10);
+ multipoint2.add(0, 0);
+
+ scl = "FF0FFF0F2";
+ res = op.execute(polyline1, multipoint2, sr, scl, null);
+ assertTrue(res);
}
@Test
- public static void testMultiPointMultipointRelate() {
+ public void testMultiPointMultipointRelate() {
OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Relate));
SpatialReference sr = SpatialReference.create(4326);
@@ -4659,42 +5396,136 @@ public static void testMultiPointMultipointRelate() {
res = GeometryEngine.relate(multipoint1, multipoint2, sr, scl);
assertTrue(res);
+
+ multipoint1.setEmpty();
+ multipoint2.setEmpty();
+
+ multipoint1.add(0, 0);
+ multipoint2.add(1, 1);
+
+ scl = "FFTFFF0FT";
+ res = op.execute(multipoint1, multipoint2, sr, scl, null);
+ assertTrue(res);
}
- @Test
- public static void testPolylinePointRelate() {
- OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Relate));
- SpatialReference sr = SpatialReference.create(4326);
- boolean res;
- String scl;
+ @Test
+ public void testPolylinePointRelate()
+ {
+ OperatorRelate op = OperatorRelate.local();
+ SpatialReference sr = SpatialReference.create(4326);
+ boolean res;
+ String scl;
- Polyline polyline = new Polyline();
- Point point = new Point();
+ Polyline polyline = new Polyline();
+ Point point = new Point();
- polyline.startPath(0, 2);
- polyline.lineTo(0, 4);
+ polyline.startPath(0, 2);
+ polyline.lineTo(0, 4);
- point.setXY(0, 3);
+ point.setXY(0, 3);
- scl = "0F1FF0FF2'";
- res = op.execute(polyline, point, sr, scl, null);
- assertTrue(res);
- }
+ scl = "0F1FF0FF2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
- static MapGeometry importFromJson(String jsonString) {
- JsonFactory factory = new JsonFactory();
- try {
- JsonParser jsonParser = factory.createJsonParser(jsonString);
- jsonParser.nextToken();
- OperatorImportFromJson importer = (OperatorImportFromJson) OperatorFactoryLocal
- .getInstance().getOperator(
- Operator.Type.ImportFromJson);
-
- return importer.execute(Geometry.Type.Unknown, jsonParser);
- } catch (Exception ex) {
- }
+ point.setXY(1, 3);
+
+ scl = "FF1FF00F2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ polyline.lineTo(4, 4);
+ polyline.lineTo(4, 2);
+ polyline.lineTo(0, 2); // no bounadry
+ point.setXY(0, 3);
+
+ scl = "0F1FFFFF2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ scl = "0F1FFFFF2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ point.setXY(1, 3);
+
+ scl = "FF1FFF0F2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ point.setXY(10, 10);
+
+ scl = "FF1FFF0F2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ polyline.setEmpty();
+ point.setEmpty();
- return null;
+ polyline.startPath(10, 10);
+ polyline.lineTo(10, 10);
+ point.setXY(10, 10);
+
+ scl = "0FFFFFFF2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ polyline.startPath(12, 12);
+ polyline.lineTo(12, 12);
+
+ scl = "0F0FFFFF2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ polyline.setEmpty();
+ point.setEmpty();
+
+ polyline.startPath(10, 10);
+ polyline.lineTo(10, 10);
+ point.setXY(0, 0);
+
+ scl = "FF0FFF0F2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+ }
+
+ @Test
+ public void testCrosses_github_issue_40() {
+ // Issue 40: Acceleration without a spatial reference changes the result
+ // of relation operators
+ Geometry geom1 = OperatorImportFromWkt.local().execute(0,
+ Geometry.Type.Unknown, "LINESTRING (2 0, 2 3)", null);
+ Geometry geom2 = OperatorImportFromWkt.local().execute(0,
+ Geometry.Type.Unknown, "POLYGON ((1 1, 4 1, 4 4, 1 4, 1 1))",
+ null);
+ boolean answer1 = OperatorCrosses.local().execute(geom1, geom2, null,
+ null);
+ assertTrue(answer1);
+ OperatorCrosses.local().accelerateGeometry(geom1, null,
+ GeometryAccelerationDegree.enumHot);
+ boolean answer2 = OperatorCrosses.local().execute(geom1, geom2, null,
+ null);
+ assertTrue(answer2);
+ }
+
+ @Test
+ public void testDisjointCrash() {
+ Polygon g1 = new Polygon();
+ g1.addEnvelope(Envelope2D.construct(0, 0, 10, 10), false);
+ Polygon g2 = new Polygon();
+ g2.addEnvelope(Envelope2D.construct(10, 1, 21, 21), false);
+ g1 = (Polygon)OperatorDensifyByLength.local().execute(g1, 0.1, null);
+ OperatorDisjoint.local().accelerateGeometry(g1, SpatialReference.create(4267), GeometryAccelerationDegree.enumHot);
+ boolean res = OperatorDisjoint.local().execute(g1, g2, SpatialReference.create(4267), null);
+ assertTrue(!res);
+ }
+
+ @Test
+ public void testDisjointFail() {
+ MapGeometry geometry1 = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, "{\"paths\":[[[3,3],[3,3]]],\"spatialReference\":{\"wkid\":4326}}");
+ MapGeometry geometry2 = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, "{\"rings\":[[[2,2],[2,4],[4,4],[4,2],[2,2]]],\"spatialReference\":{\"wkid\":4326}}");
+ OperatorDisjoint.local().accelerateGeometry(geometry1.getGeometry(), geometry1.getSpatialReference(), GeometryAccelerationDegree.enumMedium);
+ boolean res = OperatorDisjoint.local().execute(geometry1.getGeometry(), geometry2.getGeometry(), geometry1.getSpatialReference(), null);
+ assertTrue(!res);
}
}
diff --git a/src/test/java/com/esri/core/geometry/TestSerialization.java b/src/test/java/com/esri/core/geometry/TestSerialization.java
new file mode 100644
index 00000000..5f3796a1
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestSerialization.java
@@ -0,0 +1,496 @@
+/*
+ Copyright 1995-2018 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class TestSerialization extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testSerializePoint() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ Point pt = new Point(10, 40);
+ oo.writeObject(pt);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ Point ptRes = (Point) ii.readObject();
+ assertTrue(ptRes.equals(pt));
+ } catch (Exception ex) {
+ fail("Point serialization failure");
+
+ }
+
+ //try
+ //{
+ //FileOutputStream streamOut = new FileOutputStream("c:/temp/savedPoint1.txt");
+ //ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ //Point pt = new Point(10, 40, 2);
+ //oo.writeObject(pt);
+ //}
+ //catch(Exception ex)
+ //{
+ //fail("Point serialization failure");
+ //}
+
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedPoint.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Point ptRes = (Point) ii.readObject();
+ assertTrue(ptRes.getX() == 10 && ptRes.getY() == 40);
+ } catch (Exception ex) {
+ fail("Point serialization failure");
+ }
+
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedPoint1.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Point ptRes = (Point) ii.readObject();
+ assertTrue(ptRes.getX() == 10 && ptRes.getY() == 40 && ptRes.getZ() == 2);
+ } catch (Exception ex) {
+ fail("Point serialization failure");
+ }
+
+ }
+
+ @Test
+ public void testSerializePolygon() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ Polygon pt = new Polygon();
+ pt.startPath(10, 10);
+ pt.lineTo(100, 100);
+ pt.lineTo(200, 100);
+ oo.writeObject(pt);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ Polygon ptRes = (Polygon) ii.readObject();
+ assertTrue(ptRes.equals(pt));
+ } catch (Exception ex) {
+ fail("Polygon serialization failure");
+ }
+
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ Polygon pt = new Polygon();
+ pt.startPath(10, 10);
+ pt.lineTo(100, 100);
+ pt.lineTo(200, 100);
+ pt = (Polygon) GeometryEngine.simplify(pt, null);
+ oo.writeObject(pt);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ Polygon ptRes = (Polygon) ii.readObject();
+ assertTrue(ptRes.equals(pt));
+ } catch (Exception ex) {
+ fail("Polygon serialization failure");
+ }
+
+ //try
+ //{
+ //FileOutputStream streamOut = new FileOutputStream("c:/temp/savedPolygon1.txt");
+ //ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ //Polygon pt = new Polygon();
+ //pt.startPath(10, 10);
+ //pt.lineTo(100, 100);
+ //pt.lineTo(200, 100);
+ //pt = (Polygon)GeometryEngine.simplify(pt, null);
+ //oo.writeObject(pt);
+ //}
+ //catch(Exception ex)
+ //{
+ //fail("Polygon serialization failure");
+ //}
+
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedPolygon.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Polygon ptRes = (Polygon) ii.readObject();
+ assertTrue(ptRes != null);
+ } catch (Exception ex) {
+ fail("Polygon serialization failure");
+ }
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedPolygon1.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Polygon ptRes = (Polygon) ii.readObject();
+ assertTrue(ptRes != null);
+ } catch (Exception ex) {
+ fail("Polygon serialization failure");
+ }
+ }
+
+ @Test
+ public void testSerializePolyline() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ Polyline pt = new Polyline();
+ pt.startPath(10, 10);
+ pt.lineTo(100, 100);
+ pt.lineTo(200, 100);
+ oo.writeObject(pt);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ Polyline ptRes = (Polyline) ii.readObject();
+ assertTrue(ptRes.equals(pt));
+ } catch (Exception ex) {
+ fail("Polyline serialization failure");
+ }
+
+ //try
+ //{
+ //FileOutputStream streamOut = new FileOutputStream("c:/temp/savedPolyline1.txt");
+ //ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ //Polyline pt = new Polyline();
+ //pt.startPath(10, 10);
+ //pt.lineTo(100, 100);
+ //pt.lineTo(200, 100);
+ //oo.writeObject(pt);
+ //}
+ //catch(Exception ex)
+ //{
+ //fail("Polyline serialization failure");
+ //}
+
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedPolyline.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Polyline ptRes = (Polyline) ii.readObject();
+ assertTrue(ptRes != null);
+ } catch (Exception ex) {
+ fail("Polyline serialization failure");
+ }
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedPolyline1.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Polyline ptRes = (Polyline) ii.readObject();
+ assertTrue(ptRes != null);
+ } catch (Exception ex) {
+ fail("Polyline serialization failure");
+ }
+ }
+
+ @Test
+ public void testSerializeEnvelope() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ Envelope pt = new Envelope(10, 10, 400, 300);
+ oo.writeObject(pt);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ Envelope ptRes = (Envelope) ii.readObject();
+ assertTrue(ptRes.equals(pt));
+ } catch (Exception ex) {
+ fail("Envelope serialization failure");
+ }
+
+ //try
+ //{
+ //FileOutputStream streamOut = new FileOutputStream("c:/temp/savedEnvelope1.txt");
+ //ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ //Envelope pt = new Envelope(10, 10, 400, 300);
+ //oo.writeObject(pt);
+ //}
+ //catch(Exception ex)
+ //{
+ //fail("Envelope serialization failure");
+ //}
+
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedEnvelope.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Envelope ptRes = (Envelope) ii.readObject();
+ assertTrue(ptRes.getXMax() == 400);
+ } catch (Exception ex) {
+ fail("Envelope serialization failure");
+ }
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedEnvelope1.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Envelope ptRes = (Envelope) ii.readObject();
+ assertTrue(ptRes.getXMax() == 400);
+ } catch (Exception ex) {
+ fail("Envelope serialization failure");
+ }
+ }
+
+ @Test
+ public void testSerializeMultiPoint() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ MultiPoint pt = new MultiPoint();
+ pt.add(10, 30);
+ pt.add(120, 40);
+ oo.writeObject(pt);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ MultiPoint ptRes = (MultiPoint) ii.readObject();
+ assertTrue(ptRes.equals(pt));
+ } catch (Exception ex) {
+ fail("MultiPoint serialization failure");
+ }
+
+ //try
+ //{
+ //FileOutputStream streamOut = new FileOutputStream("c:/temp/savedMultiPoint1.txt");
+ //ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ //MultiPoint pt = new MultiPoint();
+ //pt.add(10, 30);
+ //pt.add(120, 40);
+ //oo.writeObject(pt);
+ //}
+ //catch(Exception ex)
+ //{
+ //fail("MultiPoint serialization failure");
+ //}
+
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedMultiPoint.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ MultiPoint ptRes = (MultiPoint) ii.readObject();
+ assertTrue(ptRes.getPoint(1).getY() == 40);
+ } catch (Exception ex) {
+ fail("MultiPoint serialization failure");
+ }
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedMultiPoint1.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ MultiPoint ptRes = (MultiPoint) ii.readObject();
+ assertTrue(ptRes.getPoint(1).getY() == 40);
+ } catch (Exception ex) {
+ fail("MultiPoint serialization failure");
+ }
+ }
+
+ @Test
+ public void testSerializeLine() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ Line pt = new Line();
+ pt.setStart(new Point(10, 30));
+ pt.setEnd(new Point(120, 40));
+ oo.writeObject(pt);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ Line ptRes = (Line) ii.readObject();
+ assertTrue(ptRes.equals(pt));
+ } catch (Exception ex) {
+ // fail("Line serialization failure");
+ assertEquals(ex.getMessage(), "Cannot serialize this geometry");
+ }
+ }
+
+ @Test
+ public void testSerializeSR() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ SpatialReference sr = SpatialReference.create(102100);
+ oo.writeObject(sr);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ SpatialReference ptRes = (SpatialReference) ii.readObject();
+ assertTrue(ptRes.equals(sr));
+ } catch (Exception ex) {
+ fail("Spatial Reference serialization failure");
+ }
+ }
+
+ @Test
+ public void testSerializeEnvelope2D() {
+ try {
+ ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
+ ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+ Envelope2D env = new Envelope2D(1.213948734, 2.213948734, 11.213948734, 12.213948734);
+ oo.writeObject(env);
+ ByteArrayInputStream streamIn = new ByteArrayInputStream(
+ streamOut.toByteArray());
+ ObjectInputStream ii = new ObjectInputStream(streamIn);
+ Envelope2D envRes = (Envelope2D)ii.readObject();
+ assertTrue(envRes.equals(env));
+ } catch (Exception ex) {
+ fail("Envelope2D serialization failure");
+ }
+
+// try
+// {
+// FileOutputStream streamOut = new FileOutputStream(
+// "c:/temp/savedEnvelope2D.txt");
+// ObjectOutputStream oo = new ObjectOutputStream(streamOut);
+// Envelope2D e = new Envelope2D(177.123, 188.234, 999.122, 888.999);
+// oo.writeObject(e);
+// }
+// catch(Exception ex)
+// {
+// fail("Envelope2D serialization failure");
+// }
+
+ try {
+ InputStream s = TestSerialization.class
+ .getResourceAsStream("savedEnvelope2D.txt");
+ ObjectInputStream ii = new ObjectInputStream(s);
+ Envelope2D e = (Envelope2D) ii
+ .readObject();
+ assertTrue(e != null);
+ assertTrue(e.equals(new Envelope2D(177.123, 188.234, 999.122, 888.999)));
+ } catch (Exception ex) {
+ fail("Envelope2D serialization failure");
+ }
+ }
+
+ public void testAttributeStreamOfInt32() {
+ AttributeStreamOfInt32 a = new AttributeStreamOfInt32(0);
+ for (int i = 0; i < 100; i++)
+ a.add(i);
+
+ try {
+ // serialize
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(baos);
+ os.writeObject(a);
+ os.close();
+ baos.close();
+
+ // deserialize
+ ByteArrayInputStream bais = new ByteArrayInputStream(
+ baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ AttributeStreamOfInt32 aOut = (AttributeStreamOfInt32) in.readObject();
+ in.close();
+ bais.close();
+
+ assertTrue(aOut.size() == a.size());
+ for (int i = 0; i < 100; i++)
+ assertTrue(aOut.get(i) == a.get(i));
+
+ } catch (Exception e) {
+ fail("AttributeStreamOfInt32 serialization failure");
+ }
+
+ }
+
+ @Test
+ public void testQuadTree() {
+ MultiPoint mp = new MultiPoint();
+ int r = 124124;
+ for (int i = 0; i < 100; ++i) {
+ r = NumberUtils.nextRand(r);
+ int x = r;
+ r = NumberUtils.nextRand(r);
+ int y = r;
+ mp.add(x, y);
+ }
+
+ Envelope2D extent = new Envelope2D();
+ mp.queryEnvelope2D(extent);
+ QuadTree quadTree = new QuadTree(extent, 8);
+ Envelope2D boundingbox = new Envelope2D();
+ Point2D pt;
+
+ for (int i = 0; i < mp.getPointCount(); i++) {
+ pt = mp.getXY(i);
+ boundingbox.setCoords(pt.x, pt.y, pt.x, pt.y);
+ quadTree.insert(i, boundingbox, -1);
+ }
+
+ try {
+ // serialize
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(baos);
+ os.writeObject(quadTree);
+ os.close();
+ baos.close();
+
+ // deserialize
+ ByteArrayInputStream bais = new ByteArrayInputStream(
+ baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ QuadTree qOut = (QuadTree) in.readObject();
+ in.close();
+ bais.close();
+
+ assertTrue(quadTree.getElementCount() == qOut.getElementCount());
+ QuadTree.QuadTreeIterator iter1 = quadTree.getIterator();
+ QuadTree.QuadTreeIterator iter2 = qOut.getIterator();
+ int h1 = iter1.next();
+ int h2 = iter2.next();
+ for (; h1 != -1 && h2 != -1; h1 = iter1.next(), h2 = iter2.next()) {
+ assertTrue(quadTree.getElement(h1) == qOut.getElement(h2));
+ assertTrue(quadTree.getElementExtent(h1).equals(qOut.getElementExtent(h2)));
+ assertTrue(quadTree.getExtent(quadTree.getQuad(h1)).equals(qOut.getExtent(qOut.getQuad(h2))));
+ int c1 = quadTree.getSubTreeElementCount(quadTree.getQuad(h1));
+ int c2 = qOut.getSubTreeElementCount(qOut.getQuad(h2));
+ assertTrue(c1 == c2);
+ }
+
+ assertTrue(h1 == -1 && h2 == -1);
+
+ assertTrue(quadTree.getDataExtent().equals(qOut.getDataExtent()));
+ } catch (Exception e) {
+ fail("QuadTree serialization failure");
+ }
+
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestSimplify.java b/src/test/java/com/esri/core/geometry/TestSimplify.java
similarity index 93%
rename from unittest/com/esri/core/geometry/TestSimplify.java
rename to src/test/java/com/esri/core/geometry/TestSimplify.java
index f39ae4de..944d271d 100644
--- a/unittest/com/esri/core/geometry/TestSimplify.java
+++ b/src/test/java/com/esri/core/geometry/TestSimplify.java
@@ -1,1328 +1,1368 @@
-package com.esri.core.geometry;
-
-//import java.io.FileOutputStream;
-//import java.io.PrintStream;
-//import java.util.ArrayList;
-//import java.util.List;
-//import java.util.Random;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-import org.codehaus.jackson.JsonFactory;
-import org.junit.Test;
-
-public class TestSimplify extends TestCase {
- OperatorFactoryLocal factory = null;
- OperatorSimplify simplifyOp = null;
- OperatorSimplifyOGC simplifyOpOGC = null;
- SpatialReference sr102100 = null;
- SpatialReference sr4326 = null;
- SpatialReference sr3857 = null;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- factory = OperatorFactoryLocal.getInstance();
- simplifyOp = (OperatorSimplify) factory
- .getOperator(Operator.Type.Simplify);
- simplifyOpOGC = (OperatorSimplifyOGC) factory
- .getOperator(Operator.Type.SimplifyOGC);
- sr102100 = SpatialReference.create(102100);
- sr3857 = SpatialReference.create(3857);// PE_PCS_WGS_1984_WEB_MERCATOR_AUXSPHERE);
- sr4326 = SpatialReference.create(4326);// enum_value2(SpatialReference,
- // Code, GCS_WGS_1984));
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public Polygon makeNonSimplePolygon2() {
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 15);
- poly.lineTo(15, 15);
- poly.lineTo(15, 0);
-
- // This is an interior ring but it is clockwise
- poly.startPath(5, 5);
- poly.lineTo(5, 6);
- poly.lineTo(6, 6);
- poly.lineTo(6, 5);
-
- return poly;
- }// done
-
- /*
- * ------------>---------------->--------------- | | | (1) | | | | --->---
- * ------->------- | | | | | (5) | | | | | | --<-- | | | | (2) | | | | | | |
- * | | | | (4) | | | | | | | -->-- | | --<-- | ---<--- | | | | | |
- * -------<------- | | (3) | -------------<---------------<---------------
- * -->--
- */
-
- // Bowtie case with vertices at intersection
-
- public Polygon makeNonSimplePolygon5() {
- Polygon poly = new Polygon();
- poly.startPath(10, 0);
- poly.lineTo(0, 0);
- poly.lineTo(5, 5);
- poly.lineTo(10, 10);
- poly.lineTo(0, 10);
- poly.lineTo(5, 5);
-
- return poly;
- }// done
-
- @Test
- public void test0() {
- Polygon poly1 = new Polygon();
- poly1.addEnvelope(new Envelope(10, 10, 40, 20), false);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
- boolean res = simplifyOp.isSimpleAsFeature(poly2, null, true, null,
- null);
- assertTrue(res);
- // assertTrue(poly1.equals(poly2));
- }// done
-
- @Test
- public void test0Poly() {// simple
- Polygon poly1 = new Polygon();
- poly1.addEnvelope(new Envelope(10, 10, 40, 20), false);
- poly1.addEnvelope(new Envelope(50, 10, 100, 20), false);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
- boolean res = simplifyOp.isSimpleAsFeature(poly2, null, true, null,
- null);
- assertTrue(res);
- // assertTrue(poly1.equals(poly2));
- }// done
-
- @Test
- public void test0Polygon_Spike1() {// non-simple (spike)
- Polygon poly1 = new Polygon();
- poly1.startPath(10, 10);
- poly1.lineTo(10, 20);
- poly1.lineTo(40, 20);
- poly1.lineTo(40, 10);
- poly1.lineTo(60, 10);
- poly1.lineTo(70, 10);
-
- boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
- null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(poly2.getPointCount() == 4);
- }// done
-
- @Test
- public void test0Polygon_Spike2() {// non-simple (spikes)
- Polygon poly1 = new Polygon();
- // rectangle with a spike
- poly1.startPath(10, 10);
- poly1.lineTo(10, 20);
- poly1.lineTo(40, 20);
- poly1.lineTo(40, 10);
- poly1.lineTo(60, 10);
- poly1.lineTo(70, 10);
-
- // degenerate
- poly1.startPath(100, 100);
- poly1.lineTo(100, 120);
- poly1.lineTo(100, 130);
-
- boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
- null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(poly2.getPointCount() == 4);
- }// done
-
- @Test
- public void test0Polygon_Spike3() {// non-simple (spikes)
- Polygon poly1 = new Polygon();
- // degenerate
- poly1.startPath(100, 100);
- poly1.lineTo(100, 120);
- poly1.lineTo(100, 130);
-
- boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
- null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(poly2.isEmpty());
- }// done
-
- @Test
- public void test0PolygonSelfIntersect1() {// non-simple (self-intersection)
- Polygon poly1 = new Polygon();
- // touch uncracked
- poly1.startPath(0, 0);
- poly1.lineTo(0, 100);
- poly1.lineTo(100, 100);
- poly1.lineTo(0, 50);
- poly1.lineTo(100, 0);
-
- boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
- null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(!poly2.isEmpty());
- }// done
-
- @Test
- public void test0PolygonSelfIntersect2() {// non-simple (self-intersection)
- Polygon poly1 = new Polygon();
- poly1.startPath(0, 0);
- poly1.lineTo(0, 100);
- poly1.lineTo(100, 100);
- poly1.lineTo(-100, 0);
- // poly1.lineTo(100, 0);
-
- boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
- null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(!poly2.isEmpty());
- }// done
-
- @Test
- public void test0PolygonSelfIntersect3() {
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 15);
- poly.lineTo(15, 15);
- poly.lineTo(15, 0);
-
- // This part intersects with the first part
- poly.startPath(10, 10);
- poly.lineTo(10, 20);
- poly.lineTo(20, 20);
- poly.lineTo(20, 10);
-
- boolean res = simplifyOp
- .isSimpleAsFeature(poly, null, true, null, null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(!poly2.isEmpty());
- }// done
-
- @Test
- public void test0PolygonInteriorRing1() {
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 15);
- poly.lineTo(15, 15);
- poly.lineTo(15, 0);
-
- // This is an interior ring but it is clockwise
- poly.startPath(5, 5);
- poly.lineTo(5, 6);
- poly.lineTo(6, 6);
- poly.lineTo(6, 5);
-
- boolean res = simplifyOp
- .isSimpleAsFeature(poly, null, true, null, null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(!poly2.isEmpty());
- }// done
-
- @Test
- public void test0PolygonInteriorRing2() {
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 15);
- poly.lineTo(15, 15);
- poly.lineTo(15, 0);
-
- // This is an interior ring but it is clockwise
- poly.startPath(5, 5);
- poly.lineTo(5, 6);
- poly.lineTo(6, 6);
- poly.lineTo(6, 5);
-
- // This part intersects with the first part
- poly.startPath(10, 10);
- poly.lineTo(10, 20);
- poly.lineTo(20, 20);
- poly.lineTo(20, 10);
-
- boolean res = simplifyOp
- .isSimpleAsFeature(poly, null, true, null, null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(!poly2.isEmpty());
- }// done
-
- @Test
- public void test0PolygonInteriorRingWithCommonBoundary1() {
- // Two rings have common boundary
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 10);
- poly.lineTo(10, 10);
- poly.lineTo(10, 0);
-
- poly.startPath(10, 0);
- poly.lineTo(10, 10);
- poly.lineTo(20, 10);
- poly.lineTo(20, 0);
-
- boolean res = simplifyOp
- .isSimpleAsFeature(poly, null, true, null, null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(!poly2.isEmpty());
- }// done
-
- @Test
- public void test0PolygonInteriorRingWithCommonBoundary2() {
- // Two rings have common boundary
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 10);
- poly.lineTo(10, 10);
- poly.lineTo(10, 0);
-
- poly.startPath(10, 5);
- poly.lineTo(10, 6);
- poly.lineTo(20, 6);
- poly.lineTo(20, 5);
-
- boolean res = simplifyOp
- .isSimpleAsFeature(poly, null, true, null, null);
- assertTrue(!res);
- Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
- res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
- assertTrue(res);
- assertTrue(!poly2.isEmpty());
- }// done
-
- @Test
- public void testPolygon() {
- Polygon nonSimplePolygon = makeNonSimplePolygon();
- Polygon simplePolygon = (Polygon) simplifyOp.execute(nonSimplePolygon,
- sr3857, false, null);
-
- boolean res = simplifyOp.isSimpleAsFeature(simplePolygon, sr3857, true,
- null, null);
- assertTrue(res);
-
- @SuppressWarnings("unused")
- int partCount = simplePolygon.getPathCount();
- // assertTrue(partCount == 2);
-
- double area = simplePolygon.calculateRingArea2D(0);
- assertTrue(Math.abs(area - 300) <= 0.0001);
-
- area = simplePolygon.calculateRingArea2D(1);
- assertTrue(Math.abs(area - (-25.0)) <= 0.0001);
- }// done
-
- @Test
- public void testPolygon2() {
- Polygon nonSimplePolygon2 = makeNonSimplePolygon2();
- double area = nonSimplePolygon2.calculateRingArea2D(1);
- assertTrue(Math.abs(area - 1.0) <= 0.0001);
-
- Polygon simplePolygon2 = (Polygon) simplifyOp.execute(
- nonSimplePolygon2, sr3857, false, null);
-
- boolean res = simplifyOp.isSimpleAsFeature(simplePolygon2, sr3857,
- true, null, null);
- assertTrue(res);
-
- area = simplePolygon2.calculateRingArea2D(0);
- assertTrue(Math.abs(area - 225) <= 0.0001);
-
- area = simplePolygon2.calculateRingArea2D(1);
- assertTrue(Math.abs(area - (-1.0)) <= 0.0001);
- }// done
-
- @Test
- public void testPolygon3() {
- Polygon nonSimplePolygon3 = makeNonSimplePolygon3();
- Polygon simplePolygon3 = (Polygon) simplifyOp.execute(
- nonSimplePolygon3, sr3857, false, null);
-
- boolean res = simplifyOp.isSimpleAsFeature(simplePolygon3, sr3857,
- true, null, null);
- assertTrue(res);
-
- double area = simplePolygon3.calculateRingArea2D(0);
- assertTrue(Math.abs(area - 875) <= 0.0001);
-
- area = simplePolygon3.calculateRingArea2D(1);
- assertTrue(Math.abs(area - (-225)) <= 0.0001
- || Math.abs(area - (-50.0)) <= 0.0001);
-
- area = simplePolygon3.calculateRingArea2D(2);
- assertTrue(Math.abs(area - (-225)) <= 0.0001
- || Math.abs(area - (-50.0)) <= 0.0001);
-
- area = simplePolygon3.calculateRingArea2D(3);
- assertTrue(Math.abs(area - 25) <= 0.0001);
-
- area = simplePolygon3.calculateRingArea2D(4);
- assertTrue(Math.abs(area - 25) <= 0.0001);
- }// done
-
- @Test
- public void testPolyline() {
- Polyline nonSimplePolyline = makeNonSimplePolyline();
- Polyline simplePolyline = (Polyline) simplifyOp.execute(
- nonSimplePolyline, sr3857, false, null);
-
- int segmentCount = simplePolyline.getSegmentCount();
- assertTrue(segmentCount == 4);
- }// done
-
- @Test
- public void testPolygon4() {
- Polygon nonSimplePolygon4 = makeNonSimplePolygon4();
- Polygon simplePolygon4 = (Polygon) simplifyOp.execute(
- nonSimplePolygon4, sr3857, false, null);
- boolean res = simplifyOp.isSimpleAsFeature(simplePolygon4, sr3857,
- true, null, null);
- assertTrue(res);
-
- assertTrue(simplePolygon4.getPointCount() == 5);
- Point point = nonSimplePolygon4.getPoint(0);
- assertTrue(point.getX() == 0.0 && point.getY() == 0.0);
- point = nonSimplePolygon4.getPoint(1);
- assertTrue(point.getX() == 0.0 && point.getY() == 10.0);
- point = nonSimplePolygon4.getPoint(2);
- assertTrue(point.getX() == 10.0 && point.getY() == 10.0);
- point = nonSimplePolygon4.getPoint(3);
- assertTrue(point.getX() == 10.0 && point.getY() == 0.0);
- point = nonSimplePolygon4.getPoint(4);
- assertTrue(point.getX() == 5.0 && point.getY() == 0.0);
- }// done
-
- @Test
- public void testPolygon5() {
- Polygon nonSimplePolygon5 = makeNonSimplePolygon5();
- Polygon simplePolygon5 = (Polygon) simplifyOp.execute(
- nonSimplePolygon5, sr3857, false, null);
- assertTrue(simplePolygon5 != null);
-
- boolean res = simplifyOp.isSimpleAsFeature(simplePolygon5, sr3857,
- true, null, null);
- assertTrue(res);
-
- // FIXME Bowtie. once simplify is fixed this should result in a
- // simplified geom
-
- int pointCount = simplePolygon5.getPointCount();
- assertTrue(pointCount == 6);
-
- double area = simplePolygon5.calculateArea2D();
- assertTrue(Math.abs(area - 50.0) <= 0.001);
-
- }// done
-
- @Test
- public void testPolygon6() {
- Polygon nonSimplePolygon6 = makeNonSimplePolygon6();
- Polygon simplePolygon6 = (Polygon) simplifyOp.execute(
- nonSimplePolygon6, sr3857, false, null);
-
- boolean res = simplifyOp.isSimpleAsFeature(simplePolygon6, sr3857,
- true, null, null);
- assertTrue(res);
- }
-
- @Test
- public void testPolygon7() {
- Polygon nonSimplePolygon7 = makeNonSimplePolygon7();
- Polygon simplePolygon7 = (Polygon) simplifyOp.execute(
- nonSimplePolygon7, sr3857, false, null);
-
- boolean res = simplifyOp.isSimpleAsFeature(simplePolygon7, sr3857,
- true, null, null);
- assertTrue(res);
- }
-
- public Polygon makeNonSimplePolygon() {
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 15);
- poly.lineTo(15, 15);
- poly.lineTo(15, 0);
-
- // This is an interior ring but it is clockwise
- poly.startPath(5, 5);
- poly.lineTo(5, 6);
- poly.lineTo(6, 6);
- poly.lineTo(6, 5);
-
- // This part intersects with the first part
- poly.startPath(10, 10);
- poly.lineTo(10, 20);
- poly.lineTo(20, 20);
- poly.lineTo(20, 10);
-
- return poly;
- }// done
-
- /*
- * ------------>---------------->--------------- | | | (1) | | | | --->---
- * ------->------- | | | | | (5) | | | | | | --<-- | | | | (2) | | | | | | |
- * | | | | (4) | | | | | | | -->-- | | --<-- | ---<--- | | | | | |
- * -------<------- | | (3) | -------------<---------------<---------------
- * -->--
- */
-
- public Polygon makeNonSimplePolygon3() {
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 25);
- poly.lineTo(35, 25);
- poly.lineTo(35, 0);
-
- poly.startPath(5, 5);
- poly.lineTo(5, 15);
- poly.lineTo(10, 15);
- poly.lineTo(10, 5);
-
- poly.startPath(40, 0);
- poly.lineTo(45, 0);
- poly.lineTo(45, 5);
- poly.lineTo(40, 5);
-
- poly.startPath(20, 10);
- poly.lineTo(25, 10);
- poly.lineTo(25, 15);
- poly.lineTo(20, 15);
-
- poly.startPath(15, 5);
- poly.lineTo(15, 20);
- poly.lineTo(30, 20);
- poly.lineTo(30, 5);
-
- return poly;
- }// done
-
- public Polygon makeNonSimplePolygon4() {
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(0, 10);
- poly.lineTo(10, 10);
- poly.lineTo(10, 0);
- poly.lineTo(5, 0);
- poly.lineTo(5, 5);
- poly.lineTo(5, 0);
-
- return poly;
- }// done
-
- public Polygon makeNonSimplePolygon6() {
- Polygon poly = new Polygon();
- poly.startPath(35.34407570857744, 54.00551247713412);
- poly.lineTo(41.07663499357954, 20.0);
- poly.lineTo(40.66372033705177, 26.217432321849017);
-
- poly.startPath(42.81936574509338, 20.0);
- poly.lineTo(43.58226670584747, 20.0);
- poly.lineTo(39.29611825817084, 22.64634933678729);
- poly.lineTo(44.369873312241346, 25.81893670527215);
- poly.lineTo(42.68845660737179, 20.0);
- poly.lineTo(38.569549792944244, 56.47456192829393);
- poly.lineTo(42.79274114188401, 45.45117792578003);
- poly.lineTo(41.09512147544657, 70.0);
-
- return poly;
- }
-
- public Polygon makeNonSimplePolygon7() {
- Polygon poly = new Polygon();
-
- poly.startPath(41.987895433319686, 53.75822619011542);
- poly.lineTo(41.98789542535497, 53.75822618803151);
- poly.lineTo(40.15120412113667, 68.12604154722113);
- poly.lineTo(37.72272697311022, 67.92767094118877);
- poly.lineTo(37.147347454283086, 49.497473094145505);
- poly.lineTo(38.636627026664385, 51.036687142232736);
-
- poly.startPath(39.00920080789793, 62.063425518369016);
- poly.lineTo(38.604912643136885, 70.0);
- poly.lineTo(40.71826863485308, 43.60337143116787);
- poly.lineTo(35.34407570857744, 54.005512477134126);
- poly.lineTo(39.29611825817084, 22.64634933678729);
-
- return poly;
- }
-
- public Polyline makeNonSimplePolyline() {
- // This polyline has a short segment
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(10, 0);
- poly.lineTo(10, 10);
- poly.lineTo(10, 5);
- poly.lineTo(-5, 5);
-
- return poly;
- }// done
-
- @Test
- public void testIsSimpleBasicsPoint() {
- boolean result;
- // point is always simple
- Point pt = new Point();
- result = simplifyOp.isSimpleAsFeature(pt, sr4326, false, null, null);
- assertTrue(result);
- pt.setXY(0, 0);
- result = simplifyOp.isSimpleAsFeature(pt, sr4326, false, null, null);
- assertTrue(result);
- pt.setXY(100000, 10000);
- result = simplifyOp.isSimpleAsFeature(pt, sr4326, false, null, null);
- assertTrue(result);
- }// done
-
- @Test
- public void testIsSimpleBasicsEnvelope() {
- // Envelope is simple, when it's width and height are not degenerate
- Envelope env = new Envelope();
- boolean result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null,
- null); // Empty is simple
- assertTrue(result);
- env.setCoords(0, 0, 10, 10);
- result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null, null);
- assertTrue(result);
- // sliver but still simple
- env.setCoords(0, 0, 0 + sr4326.getTolerance() * 2, 10);
- result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null, null);
- assertTrue(result);
- // sliver and not simple
- env.setCoords(0, 0, 0 + sr4326.getTolerance() * 0.5, 10);
- result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null, null);
- assertTrue(!result);
- }// done
-
- @Test
- public void testIsSimpleBasicsLine() {
- Line line = new Line();
- boolean result = simplifyOp.isSimpleAsFeature(line, sr4326, false,
- null, null);
- assertTrue(!result);
-
- line.setStart(new Point(0, 0));
- // line.setEndXY(0, 0);
- result = simplifyOp.isSimpleAsFeature(line, sr4326, false, null, null);
- assertTrue(!result);
- line.setEnd(new Point(1, 0));
- result = simplifyOp.isSimpleAsFeature(line, sr4326, false, null, null);
- assertTrue(result);
- }// done
-
- @Test
- public void testIsSimpleMultiPoint1() {
- MultiPoint mp = new MultiPoint();
- boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
- null);
- assertTrue(result);// empty is simple
- result = simplifyOp.isSimpleAsFeature(
- simplifyOp.execute(mp, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- }// done
-
- @Test
- public void testIsSimpleMultiPoint2FarApart() {
- // Two point test: far apart
- MultiPoint mp = new MultiPoint();
- mp.add(20, 10);
- mp.add(100, 100);
- boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
- null);
- assertTrue(result);
- result = simplifyOp.isSimpleAsFeature(
- simplifyOp.execute(mp, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- assertTrue(mp.getPointCount() == 2);
- }// done
-
- @Test
- public void testIsSimpleMultiPointCoincident() {
- // Two point test: coincident
- MultiPoint mp = new MultiPoint();
- mp.add(100, 100);
- mp.add(100, 100);
- boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
- null);
- assertTrue(!result);
- MultiPoint mpS;
- result = simplifyOp.isSimpleAsFeature(
- mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
- sr4326, false, null, null);
- assertTrue(result);
- assertTrue(mpS.getPointCount() == 1);
- }// done
-
- @Test
- public void testMultiPointSR4326_CR184439() {
- OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
- OperatorSimplify simpOp = (OperatorSimplify) engine
- .getOperator(Operator.Type.Simplify);
- NonSimpleResult nonSimpResult = new NonSimpleResult();
- nonSimpResult.m_reason = NonSimpleResult.Reason.NotDetermined;
- MultiPoint multiPoint = new MultiPoint();
- multiPoint.add(0, 0);
- multiPoint.add(0, 1);
- multiPoint.add(0, 0);
- Boolean multiPointIsSimple = simpOp.isSimpleAsFeature(multiPoint,
- SpatialReference.create(4326), true, nonSimpResult, null);
- assertFalse(multiPointIsSimple);
- assertTrue(nonSimpResult.m_reason == NonSimpleResult.Reason.Clustering);
- assertTrue(nonSimpResult.m_vertexIndex1 == 0);
- assertTrue(nonSimpResult.m_vertexIndex2 == 2);
- }
-
- @Test
- public void testIsSimpleMultiPointCloserThanTolerance() {
- // Two point test: closer than tolerance
- MultiPoint mp = new MultiPoint();
- MultiPoint mpS;
- mp.add(100, 100);
- mp.add(100, 100 + sr4326.getTolerance() * .5);
- boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
- null);
- assertTrue(result);
- result = simplifyOp.isSimpleAsFeature(
- mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
- sr4326, false, null, null);
- assertTrue(result);
- assertTrue(mpS.getPointCount() == 2);
- }// done
-
- @Test
- public void testIsSimpleMultiPointFarApart2() {
- // 5 point test: far apart
- MultiPoint mp = new MultiPoint();
- mp.add(100, 100);
- mp.add(100, 101);
- mp.add(101, 101);
- mp.add(11, 1);
- mp.add(11, 14);
- MultiPoint mpS;
- boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
- null);
- assertTrue(result);
- result = simplifyOp.isSimpleAsFeature(
- mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
- sr4326, false, null, null);
- assertTrue(result);
- assertTrue(mpS.getPointCount() == 5);
- }// done
-
- @Test
- public void testIsSimpleMultiPoint_coincident2() {
- // 5 point test: coincident
- MultiPoint mp = new MultiPoint();
- mp.add(100, 100);
- mp.add(100, 101);
- mp.add(100, 100);
- mp.add(11, 1);
- mp.add(11, 14);
- boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
- null);
- assertTrue(!result);
- MultiPoint mpS;
- result = simplifyOp.isSimpleAsFeature(
- mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
- sr4326, false, null, null);
- assertTrue(result);
- assertTrue(mpS.getPointCount() == 4);
- assertEquals(mpS.getPoint(0).getX(), 100, 1e-7);
- assertEquals(mpS.getPoint(0).getY(), 100, 1e-7);
- assertEquals(mpS.getPoint(1).getX(), 100, 1e-7);
- assertEquals(mpS.getPoint(1).getY(), 101, 1e-7);
- assertEquals(mpS.getPoint(2).getX(), 11, 1e-7);
- assertEquals(mpS.getPoint(2).getY(), 1, 1e-7);
- assertEquals(mpS.getPoint(3).getX(), 11, 1e-7);
- assertEquals(mpS.getPoint(3).getY(), 14, 1e-7);
- }// done
-
- @Test
- public void testIsSimpleMultiPointCloserThanTolerance2() {
- // 5 point test: closer than tolerance
- MultiPoint mp = new MultiPoint();
- mp.add(100, 100);
- mp.add(100, 101);
- mp.add(100, 100 + sr4326.getTolerance() / 2);
- mp.add(11, 1);
- mp.add(11, 14);
- MultiPoint mpS;
- boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
- null);
- assertTrue(result);
- result = simplifyOp.isSimpleAsFeature(
- mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
- sr4326, false, null, null);
- assertTrue(result);
- assertTrue(mpS.getPointCount() == 5);
- }// done
-
- @Test
- public void testIsSimplePolyline() {
- Polyline poly = new Polyline();
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);// empty is simple
- }
-
- @Test
- public void testIsSimplePolylineFarApart() {
- // Two point test: far apart
- Polyline poly = new Polyline();
- poly.startPath(20, 10);
- poly.lineTo(100, 100);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);
- }
-
- @Test
- public void testIsSimplePolylineCoincident() {
- // Two point test: coincident
- Polyline poly = new Polyline();
- poly.startPath(100, 100);
- poly.lineTo(100, 100);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- @SuppressWarnings("unused")
- Polyline polyS;
- result = simplifyOp.isSimpleAsFeature(
- polyS = (Polyline) simplifyOp
- .execute(poly, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- }
-
- @Test
- public void testIsSimplePolylineCloserThanTolerance() {
- // Two point test: closer than tolerance
- Polyline poly = new Polyline();
- poly.startPath(100, 100);
- poly.lineTo(100, 100 + sr4326.getTolerance() / 2);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- @SuppressWarnings("unused")
- Polyline polyS;
- result = simplifyOp.isSimpleAsFeature(
- polyS = (Polyline) simplifyOp
- .execute(poly, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- }
-
- @Test
- public void testIsSimplePolylineFarApartSelfOverlap0() {
- // 3 point test: far apart, self overlapping
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.lineTo(0, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);// TO CONFIRM should be false
- }
-
- @Test
- public void testIsSimplePolylineSelfIntersect() {
- // 4 point test: far apart, self intersecting
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.lineTo(0, 100);
- poly.lineTo(100, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);// TO CONFIRM should be false
- }
-
- @Test
- public void testIsSimplePolylineDegenerateSegment() {
- // 4 point test: degenerate segment
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.lineTo(100, 100 + sr4326.getTolerance() / 2);
- poly.lineTo(100, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- @SuppressWarnings("unused")
- Polyline polyS;
- result = simplifyOp.isSimpleAsFeature(
- polyS = (Polyline) simplifyOp
- .execute(poly, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- {
- Polyline other = new Polyline();
- other.startPath(0, 0);
- other.lineTo(100, 100);
- other.lineTo(100, 0);
- other.equals(poly);
- }
- }
-
- @Test
- public void testIsSimplePolylineFarApartSelfOverlap() {
- // 3 point test: far apart, self overlapping
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.lineTo(0, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);// TO CONFIRM should be false
- }
-
- @Test
- public void testIsSimplePolylineFarApartIntersect() {
- // 4 point 2 parts test: far apart, intersecting parts
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.startPath(100, 0);
- poly.lineTo(0, 100);
-
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);// TO CONFIRM should be false
- }
-
- @Test
- public void testIsSimplePolylineFarApartOverlap2() {
- // 4 point 2 parts test: far apart, overlapping parts. second part
- // starts where first one ends
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.startPath(100, 100);
- poly.lineTo(0, 100);
-
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);// TO CONFIRM should be false
- }
-
- @Test
- public void testIsSimplePolylineDegenerateVertical() {
- // 3 point test: degenerate vertical line
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(new Point(100, 100));
- poly.lineTo(new Point(100, 100));
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- Polyline polyS;
- result = simplifyOp.isSimpleAsFeature(
- polyS = (Polyline) simplifyOp
- .execute(poly, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- assertTrue(polyS.getPointCount() == 2);
- }
-
- @Test
- public void testIsSimplePolylineEmptyPath() {
- // TODO: any way to test this?
- // Empty path
- // Polyline poly = new Polyline();
- // assertTrue(poly.isEmpty());
- // poly.addPath(new Polyline(), 0, true);
- // assertTrue(poly.isEmpty());
- // boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- // null, null);
- // assertTrue(result);
- }
-
- @Test
- public void testIsSimplePolylineSinglePointInPath() {
- // Single point in path
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.removePoint(0, 1);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- Polyline polyS;
- result = simplifyOp.isSimpleAsFeature(
- polyS = (Polyline) simplifyOp
- .execute(poly, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- assertTrue(polyS.isEmpty());
- }
-
- @Test
- public void testIsSimplePolygon() {
- Polygon poly = new Polygon();
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);// empty is simple
- result = simplifyOp.isSimpleAsFeature(
- simplifyOp.execute(poly, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);// empty is simple
- }
-
- @Test
- public void testIsSimplePolygonEmptyPath() {
- // TODO:
- // Empty path
- // Polygon poly = new Polygon();
- // poly.addPath(new Polyline(), 0, true);
- // assertTrue(poly.getPathCount() == 1);
- // boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- // null,
- // null);
- // assertTrue(result);
- // result = simplifyOp.isSimpleAsFeature(simplifyOp.execute(poly,
- // sr4326, false, null), sr4326, false, null, null);
- // assertTrue(result);// empty is simple
- // assertTrue(poly.getPathCount() == 1);
- }
-
- @Test
- public void testIsSimplePolygonIncomplete1() {
- // Incomplete polygon 1
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- // poly.removePoint(0, 1);//TO CONFIRM no removePoint method in Java
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonIncomplete2() {
- // Incomplete polygon 2
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonDegenerateTriangle() {
- // Degenerate triangle (self overlap)
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.lineTo(0, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonSelfIntersect() {
- // Self intersection - cracking is needed
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.lineTo(0, 100);
- poly.lineTo(100, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonRectangleHole() {
- // Rectangle and rectangular hole that has one segment overlapping
- // with the with the exterior ring. Cracking is needed.
- Polygon poly = new Polygon();
- poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
- poly.addEnvelope(new Envelope(-100, -100, 100, 50), true);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- poly.reverseAllPaths();
- result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonRectangleHole2() {
- // Rectangle and rectangular hole
- Polygon poly = new Polygon();
- poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
- poly.addEnvelope(new Envelope(-100, -50, 100, 50), true);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);
- poly.reverseAllPaths();
- result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonSelfIntersectAtVertex() {
- // Self intersection at vertex
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(50, 50);
- poly.lineTo(100, 100);
- poly.lineTo(0, 100);
- poly.lineTo(50, 50);
- poly.lineTo(100, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- result = simplifyOp.isSimpleAsFeature(
- simplifyOp.execute(poly, sr4326, false, null), sr4326, false,
- null, null);
- assertTrue(result);
- }
-
- @Test
- public void testIsSimplePolygon_2EdgesTouchAtVertex() {
- // No self-intersection, but more than two edges touch at the same
- // vertex. Simple for ArcGIS, not simple for OGC
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(50, 50);
- poly.lineTo(0, 100);
- poly.lineTo(100, 100);
- poly.lineTo(50, 50);
- poly.lineTo(100, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);
- }
-
- @Test
- public void testIsSimplePolygonTriangle() {
- // Triangle
- Polygon poly = new Polygon();
- poly.startPath(0, 0);
- poly.lineTo(100, 100);
- poly.lineTo(100, 0);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);
- poly.reverseAllPaths();
- result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonRectangle() {
- // Rectangle
- Polygon poly = new Polygon();
- poly.addEnvelope(new Envelope(-200, -100, 100, 200), false);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);
- poly.reverseAllPaths();
- result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonRectangleHoleWrongDirection() {
- // Rectangle and rectangular hole that has wrong direction
- Polygon poly = new Polygon();
- poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
- poly.addEnvelope(new Envelope(-100, -50, 100, 50), false);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(!result);
- poly.reverseAllPaths();
- result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygon_2RectanglesSideBySide() {
- // Two rectangles side by side, simple
- Polygon poly = new Polygon();
- poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
- poly.addEnvelope(new Envelope(220, -50, 300, 50), false);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);
- poly.reverseAllPaths();
- result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testIsSimplePolygonRectangleOneBelow() {
- // Two rectangles one below another, simple
- Polygon poly = new Polygon();
- poly.addEnvelope(new Envelope(50, 50, 100, 100), false);
- poly.addEnvelope(new Envelope(50, 200, 100, 250), false);
- boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
- null, null);
- assertTrue(result);
- poly.reverseAllPaths();
- result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
- assertTrue(!result);
- }
-
- @Test
- public void testisSimpleOGC() {
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(10, 0);
- boolean result = simplifyOpOGC.isSimpleOGC(poly, sr4326, true, null,
- null);
- assertTrue(result);
-
- poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(10, 10);
- poly.lineTo(0, 10);
- poly.lineTo(10, 0);
- NonSimpleResult nsr = new NonSimpleResult();
- result = simplifyOpOGC.isSimpleOGC(poly, sr4326, true, nsr, null);
- assertTrue(!result);
- assertTrue(nsr.m_reason == NonSimpleResult.Reason.Cracking);
-
- MultiPoint mp = new MultiPoint();
- mp.add(0, 0);
- mp.add(10, 0);
- result = simplifyOpOGC.isSimpleOGC(mp, sr4326, true, null, null);
- assertTrue(result);
-
- mp = new MultiPoint();
- mp.add(10, 0);
- mp.add(10, 0);
- nsr = new NonSimpleResult();
- result = simplifyOpOGC.isSimpleOGC(mp, sr4326, true, nsr, null);
- assertTrue(!result);
- assertTrue(nsr.m_reason == NonSimpleResult.Reason.Clustering);
- }
-
- @Test
- public void testPolylineIsSimpleForOGC() throws IOException {
- OperatorImportFromJson importerJson = (OperatorImportFromJson) factory
- .getOperator(Operator.Type.ImportFromJson);
- OperatorSimplify simplify = (OperatorSimplify) factory
- .getOperator(Operator.Type.Simplify);
-
- JsonFactory f = new JsonFactory();
-
- {
- String s = "{\"paths\":[[[0, 10], [8, 5], [5, 2], [6, 0]]]}";
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(res);
- }
- {
- String s = "{\"paths\":[[[0, 10], [6, 0], [7, 5], [0, 3]]]}";// self
- // intersection
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(!res);
- }
-
- {
- String s = "{\"paths\":[[[0, 10], [6, 0], [0, 3], [0, 10]]]}"; // closed
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(res);
- }
-
- {
- String s = "{\"paths\":[[[0, 10], [5, 5], [6, 0], [0, 3], [5, 5], [0, 9], [0, 10]]]}"; // closed
- // with
- // self
- // tangent
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(!res);
- }
-
- {
- String s = "{\"paths\":[[[0, 10], [5, 2]], [[5, 2], [6, 0]]]}";// two
- // paths
- // connected
- // at
- // a
- // point
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(res);
- }
-
- {
- String s = "{\"paths\":[[[0, 0], [3, 3], [5, 0], [0, 0]], [[0, 10], [3, 3], [10, 10], [0, 10]]]}";// two
- // closed
- // rings
- // touch
- // at
- // one
- // point
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(!res);
- }
-
- {
- String s = "{\"paths\":[[[0, 0], [10, 10]], [[0, 10], [10, 0]]]}";// two
- // lines
- // intersect
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(!res);
- }
-
- {
- String s = "{\"paths\":[[[0, 0], [5, 5], [0, 10]], [[10, 10], [5, 5], [10, 0]]]}";// two
- // paths
- // share
- // mid
- // point.
- Geometry g = importerJson.execute(Geometry.Type.Unknown,
- f.createJsonParser(s)).getGeometry();
- boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
- assertTrue(!res);
- }
-
- }
-
-}
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+//import java.io.FileOutputStream;
+//import java.io.PrintStream;
+//import java.util.ArrayList;
+//import java.util.List;
+//import java.util.Random;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonFactory;
+
+public class TestSimplify extends TestCase {
+ OperatorFactoryLocal factory = null;
+ OperatorSimplify simplifyOp = null;
+ OperatorSimplifyOGC simplifyOpOGC = null;
+ SpatialReference sr102100 = null;
+ SpatialReference sr4326 = null;
+ SpatialReference sr3857 = null;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = OperatorFactoryLocal.getInstance();
+ simplifyOp = (OperatorSimplify) factory
+ .getOperator(Operator.Type.Simplify);
+ simplifyOpOGC = (OperatorSimplifyOGC) factory
+ .getOperator(Operator.Type.SimplifyOGC);
+ sr102100 = SpatialReference.create(102100);
+ sr3857 = SpatialReference.create(3857);// PE_PCS_WGS_1984_WEB_MERCATOR_AUXSPHERE);
+ sr4326 = SpatialReference.create(4326);// enum_value2(SpatialReference,
+ // Code, GCS_WGS_1984));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public Polygon makeNonSimplePolygon2() {
+ //MapGeometry mg = OperatorFactoryLocal.loadGeometryFromJSONFileDbg("c:/temp/simplify_polygon_gnomonic.txt");
+ //Geometry res = OperatorSimplify.local().execute(mg.getGeometry(), mg.getSpatialReference(), true, null);
+
+
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 15);
+ poly.lineTo(15, 15);
+ poly.lineTo(15, 0);
+
+ // This is an interior ring but it is clockwise
+ poly.startPath(5, 5);
+ poly.lineTo(5, 6);
+ poly.lineTo(6, 6);
+ poly.lineTo(6, 5);
+
+ return poly;
+ }// done
+
+ /*
+ * ------------>---------------->--------------- | | | (1) | | | | --->---
+ * ------->------- | | | | | (5) | | | | | | --<-- | | | | (2) | | | | | | |
+ * | | | | (4) | | | | | | | -->-- | | --<-- | ---<--- | | | | | |
+ * -------<------- | | (3) | -------------<---------------<---------------
+ * -->--
+ */
+
+ // Bowtie case with vertices at intersection
+
+ public Polygon makeNonSimplePolygon5() {
+ Polygon poly = new Polygon();
+ poly.startPath(10, 0);
+ poly.lineTo(0, 0);
+ poly.lineTo(5, 5);
+ poly.lineTo(10, 10);
+ poly.lineTo(0, 10);
+ poly.lineTo(5, 5);
+
+ return poly;
+ }// done
+
+ @Test
+ public void test0() {
+ Polygon poly1 = new Polygon();
+ poly1.addEnvelope(new Envelope(10, 10, 40, 20), false);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
+ boolean res = simplifyOp.isSimpleAsFeature(poly2, null, true, null,
+ null);
+ assertTrue(res);
+ // assertTrue(poly1.equals(poly2));
+ }// done
+
+ @Test
+ public void test0Poly() {// simple
+ Polygon poly1 = new Polygon();
+ poly1.addEnvelope(new Envelope(10, 10, 40, 20), false);
+ poly1.addEnvelope(new Envelope(50, 10, 100, 20), false);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
+ boolean res = simplifyOp.isSimpleAsFeature(poly2, null, true, null,
+ null);
+ assertTrue(res);
+ // assertTrue(poly1.equals(poly2));
+ }// done
+
+ @Test
+ public void test0Polygon_Spike1() {// non-simple (spike)
+ Polygon poly1 = new Polygon();
+ poly1.startPath(10, 10);
+ poly1.lineTo(10, 20);
+ poly1.lineTo(40, 20);
+ poly1.lineTo(40, 10);
+ poly1.lineTo(60, 10);
+ poly1.lineTo(70, 10);
+
+ boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
+ null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(poly2.getPointCount() == 4);
+ }// done
+
+ @Test
+ public void test0Polygon_Spike2() {// non-simple (spikes)
+ Polygon poly1 = new Polygon();
+ // rectangle with a spike
+ poly1.startPath(10, 10);
+ poly1.lineTo(10, 20);
+ poly1.lineTo(40, 20);
+ poly1.lineTo(40, 10);
+ poly1.lineTo(60, 10);
+ poly1.lineTo(70, 10);
+
+ // degenerate
+ poly1.startPath(100, 100);
+ poly1.lineTo(100, 120);
+ poly1.lineTo(100, 130);
+
+ boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
+ null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(poly2.getPointCount() == 4);
+ }// done
+
+ @Test
+ public void test0Polygon_Spike3() {// non-simple (spikes)
+ Polygon poly1 = new Polygon();
+ // degenerate
+ poly1.startPath(100, 100);
+ poly1.lineTo(100, 120);
+ poly1.lineTo(100, 130);
+
+ boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
+ null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(poly2.isEmpty());
+ }// done
+
+ @Test
+ public void test0PolygonSelfIntersect1() {// non-simple (self-intersection)
+ Polygon poly1 = new Polygon();
+ // touch uncracked
+ poly1.startPath(0, 0);
+ poly1.lineTo(0, 100);
+ poly1.lineTo(100, 100);
+ poly1.lineTo(0, 50);
+ poly1.lineTo(100, 0);
+
+ boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
+ null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(!poly2.isEmpty());
+ }// done
+
+ @Test
+ public void test0PolygonSelfIntersect2() {// non-simple (self-intersection)
+ Polygon poly1 = new Polygon();
+ poly1.startPath(0, 0);
+ poly1.lineTo(0, 100);
+ poly1.lineTo(100, 100);
+ poly1.lineTo(-100, 0);
+ // poly1.lineTo(100, 0);
+
+ boolean res = simplifyOp.isSimpleAsFeature(poly1, null, true, null,
+ null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly1, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(!poly2.isEmpty());
+ }// done
+
+ @Test
+ public void test0PolygonSelfIntersect3() {
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 15);
+ poly.lineTo(15, 15);
+ poly.lineTo(15, 0);
+
+ // This part intersects with the first part
+ poly.startPath(10, 10);
+ poly.lineTo(10, 20);
+ poly.lineTo(20, 20);
+ poly.lineTo(20, 10);
+
+ boolean res = simplifyOp
+ .isSimpleAsFeature(poly, null, true, null, null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(!poly2.isEmpty());
+ }// done
+
+ @Test
+ public void test0PolygonInteriorRing1() {
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 15);
+ poly.lineTo(15, 15);
+ poly.lineTo(15, 0);
+
+ // This is an interior ring but it is clockwise
+ poly.startPath(5, 5);
+ poly.lineTo(5, 6);
+ poly.lineTo(6, 6);
+ poly.lineTo(6, 5);
+
+ boolean res = simplifyOp
+ .isSimpleAsFeature(poly, null, true, null, null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(!poly2.isEmpty());
+ }// done
+
+ @Test
+ public void test0PolygonInteriorRing2() {
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 15);
+ poly.lineTo(15, 15);
+ poly.lineTo(15, 0);
+
+ // This is an interior ring but it is clockwise
+ poly.startPath(5, 5);
+ poly.lineTo(5, 6);
+ poly.lineTo(6, 6);
+ poly.lineTo(6, 5);
+
+ // This part intersects with the first part
+ poly.startPath(10, 10);
+ poly.lineTo(10, 20);
+ poly.lineTo(20, 20);
+ poly.lineTo(20, 10);
+
+ boolean res = simplifyOp
+ .isSimpleAsFeature(poly, null, true, null, null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(!poly2.isEmpty());
+ }// done
+
+ @Test
+ public void test0PolygonInteriorRingWithCommonBoundary1() {
+ // Two rings have common boundary
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 10);
+ poly.lineTo(10, 10);
+ poly.lineTo(10, 0);
+
+ poly.startPath(10, 0);
+ poly.lineTo(10, 10);
+ poly.lineTo(20, 10);
+ poly.lineTo(20, 0);
+
+ boolean res = simplifyOp
+ .isSimpleAsFeature(poly, null, true, null, null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(!poly2.isEmpty());
+ }// done
+
+ @Test
+ public void test0PolygonInteriorRingWithCommonBoundary2() {
+ // Two rings have common boundary
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 10);
+ poly.lineTo(10, 10);
+ poly.lineTo(10, 0);
+
+ poly.startPath(10, 5);
+ poly.lineTo(10, 6);
+ poly.lineTo(20, 6);
+ poly.lineTo(20, 5);
+
+ boolean res = simplifyOp
+ .isSimpleAsFeature(poly, null, true, null, null);
+ assertTrue(!res);
+ Polygon poly2 = (Polygon) simplifyOp.execute(poly, null, false, null);
+ res = simplifyOp.isSimpleAsFeature(poly2, null, true, null, null);
+ assertTrue(res);
+ assertTrue(!poly2.isEmpty());
+ }// done
+
+ @Test
+ public void testPolygon() {
+ Polygon nonSimplePolygon = makeNonSimplePolygon();
+ Polygon simplePolygon = (Polygon) simplifyOp.execute(nonSimplePolygon,
+ sr3857, false, null);
+
+ boolean res = simplifyOp.isSimpleAsFeature(simplePolygon, sr3857, true,
+ null, null);
+ assertTrue(res);
+
+ @SuppressWarnings("unused")
+ int partCount = simplePolygon.getPathCount();
+ // assertTrue(partCount == 2);
+
+ double area = simplePolygon.calculateRingArea2D(0);
+ assertTrue(Math.abs(area - 300) <= 0.0001);
+
+ area = simplePolygon.calculateRingArea2D(1);
+ assertTrue(Math.abs(area - (-25.0)) <= 0.0001);
+ }// done
+
+ @Test
+ public void testPolygon2() {
+ Polygon nonSimplePolygon2 = makeNonSimplePolygon2();
+ double area = nonSimplePolygon2.calculateRingArea2D(1);
+ assertTrue(Math.abs(area - 1.0) <= 0.0001);
+
+ Polygon simplePolygon2 = (Polygon) simplifyOp.execute(
+ nonSimplePolygon2, sr3857, false, null);
+
+ boolean res = simplifyOp.isSimpleAsFeature(simplePolygon2, sr3857,
+ true, null, null);
+ assertTrue(res);
+
+ area = simplePolygon2.calculateRingArea2D(0);
+ assertTrue(Math.abs(area - 225) <= 0.0001);
+
+ area = simplePolygon2.calculateRingArea2D(1);
+ assertTrue(Math.abs(area - (-1.0)) <= 0.0001);
+ }// done
+
+ @Test
+ public void testPolygon3() {
+ Polygon nonSimplePolygon3 = makeNonSimplePolygon3();
+ Polygon simplePolygon3 = (Polygon) simplifyOp.execute(
+ nonSimplePolygon3, sr3857, false, null);
+
+ boolean res = simplifyOp.isSimpleAsFeature(simplePolygon3, sr3857,
+ true, null, null);
+ assertTrue(res);
+
+ double area = simplePolygon3.calculateRingArea2D(0);
+ assertTrue(Math.abs(area - 875) <= 0.0001);
+
+ area = simplePolygon3.calculateRingArea2D(1);
+ assertTrue(Math.abs(area - (-225)) <= 0.0001
+ || Math.abs(area - (-50.0)) <= 0.0001);
+
+ area = simplePolygon3.calculateRingArea2D(2);
+ assertTrue(Math.abs(area - (-225)) <= 0.0001
+ || Math.abs(area - (-50.0)) <= 0.0001);
+
+ area = simplePolygon3.calculateRingArea2D(3);
+ assertTrue(Math.abs(area - 25) <= 0.0001);
+
+ area = simplePolygon3.calculateRingArea2D(4);
+ assertTrue(Math.abs(area - 25) <= 0.0001);
+ }// done
+
+ @Test
+ public void testPolyline() {
+ Polyline nonSimplePolyline = makeNonSimplePolyline();
+ Polyline simplePolyline = (Polyline) simplifyOp.execute(
+ nonSimplePolyline, sr3857, false, null);
+
+ int segmentCount = simplePolyline.getSegmentCount();
+ assertTrue(segmentCount == 4);
+ }// done
+
+ @Test
+ public void testPolygon4() {
+ Polygon nonSimplePolygon4 = makeNonSimplePolygon4();
+ Polygon simplePolygon4 = (Polygon) simplifyOp.execute(
+ nonSimplePolygon4, sr3857, false, null);
+ boolean res = simplifyOp.isSimpleAsFeature(simplePolygon4, sr3857,
+ true, null, null);
+ assertTrue(res);
+
+ assertTrue(simplePolygon4.getPointCount() == 5);
+ Point point = nonSimplePolygon4.getPoint(0);
+ assertTrue(point.getX() == 0.0 && point.getY() == 0.0);
+ point = nonSimplePolygon4.getPoint(1);
+ assertTrue(point.getX() == 0.0 && point.getY() == 10.0);
+ point = nonSimplePolygon4.getPoint(2);
+ assertTrue(point.getX() == 10.0 && point.getY() == 10.0);
+ point = nonSimplePolygon4.getPoint(3);
+ assertTrue(point.getX() == 10.0 && point.getY() == 0.0);
+ point = nonSimplePolygon4.getPoint(4);
+ assertTrue(point.getX() == 5.0 && point.getY() == 0.0);
+ }// done
+
+ @Test
+ public void testPolygon5() {
+ Polygon nonSimplePolygon5 = makeNonSimplePolygon5();
+ Polygon simplePolygon5 = (Polygon) simplifyOp.execute(
+ nonSimplePolygon5, sr3857, false, null);
+ assertTrue(simplePolygon5 != null);
+
+ boolean res = simplifyOp.isSimpleAsFeature(simplePolygon5, sr3857,
+ true, null, null);
+ assertTrue(res);
+
+ int pointCount = simplePolygon5.getPointCount();
+ assertTrue(pointCount == 6);
+
+ double area = simplePolygon5.calculateArea2D();
+ assertTrue(Math.abs(area - 50.0) <= 0.001);
+
+ }// done
+
+ @Test
+ public void testPolygon6() {
+ Polygon nonSimplePolygon6 = makeNonSimplePolygon6();
+ Polygon simplePolygon6 = (Polygon) simplifyOp.execute(
+ nonSimplePolygon6, sr3857, false, null);
+
+ boolean res = simplifyOp.isSimpleAsFeature(simplePolygon6, sr3857,
+ true, null, null);
+ assertTrue(res);
+ }
+
+ @Test
+ public void testPolygon7() {
+ Polygon nonSimplePolygon7 = makeNonSimplePolygon7();
+ Polygon simplePolygon7 = (Polygon) simplifyOp.execute(
+ nonSimplePolygon7, sr3857, false, null);
+
+ boolean res = simplifyOp.isSimpleAsFeature(simplePolygon7, sr3857,
+ true, null, null);
+ assertTrue(res);
+ }
+
+ public Polygon makeNonSimplePolygon() {
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 15);
+ poly.lineTo(15, 15);
+ poly.lineTo(15, 0);
+
+ // This is an interior ring but it is clockwise
+ poly.startPath(5, 5);
+ poly.lineTo(5, 6);
+ poly.lineTo(6, 6);
+ poly.lineTo(6, 5);
+
+ // This part intersects with the first part
+ poly.startPath(10, 10);
+ poly.lineTo(10, 20);
+ poly.lineTo(20, 20);
+ poly.lineTo(20, 10);
+
+ return poly;
+ }// done
+
+ /*
+ * ------------>---------------->--------------- | | | (1) | | | | --->---
+ * ------->------- | | | | | (5) | | | | | | --<-- | | | | (2) | | | | | | |
+ * | | | | (4) | | | | | | | -->-- | | --<-- | ---<--- | | | | | |
+ * -------<------- | | (3) | -------------<---------------<---------------
+ * -->--
+ */
+
+ public Polygon makeNonSimplePolygon3() {
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 25);
+ poly.lineTo(35, 25);
+ poly.lineTo(35, 0);
+
+ poly.startPath(5, 5);
+ poly.lineTo(5, 15);
+ poly.lineTo(10, 15);
+ poly.lineTo(10, 5);
+
+ poly.startPath(40, 0);
+ poly.lineTo(45, 0);
+ poly.lineTo(45, 5);
+ poly.lineTo(40, 5);
+
+ poly.startPath(20, 10);
+ poly.lineTo(25, 10);
+ poly.lineTo(25, 15);
+ poly.lineTo(20, 15);
+
+ poly.startPath(15, 5);
+ poly.lineTo(15, 20);
+ poly.lineTo(30, 20);
+ poly.lineTo(30, 5);
+
+ return poly;
+ }// done
+
+ public Polygon makeNonSimplePolygon4() {
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(0, 10);
+ poly.lineTo(10, 10);
+ poly.lineTo(10, 0);
+ poly.lineTo(5, 0);
+ poly.lineTo(5, 5);
+ poly.lineTo(5, 0);
+
+ return poly;
+ }// done
+
+ public Polygon makeNonSimplePolygon6() {
+ Polygon poly = new Polygon();
+ poly.startPath(35.34407570857744, 54.00551247713412);
+ poly.lineTo(41.07663499357954, 20.0);
+ poly.lineTo(40.66372033705177, 26.217432321849017);
+
+ poly.startPath(42.81936574509338, 20.0);
+ poly.lineTo(43.58226670584747, 20.0);
+ poly.lineTo(39.29611825817084, 22.64634933678729);
+ poly.lineTo(44.369873312241346, 25.81893670527215);
+ poly.lineTo(42.68845660737179, 20.0);
+ poly.lineTo(38.569549792944244, 56.47456192829393);
+ poly.lineTo(42.79274114188401, 45.45117792578003);
+ poly.lineTo(41.09512147544657, 70.0);
+
+ return poly;
+ }
+
+ public Polygon makeNonSimplePolygon7() {
+ Polygon poly = new Polygon();
+
+ poly.startPath(41.987895433319686, 53.75822619011542);
+ poly.lineTo(41.98789542535497, 53.75822618803151);
+ poly.lineTo(40.15120412113667, 68.12604154722113);
+ poly.lineTo(37.72272697311022, 67.92767094118877);
+ poly.lineTo(37.147347454283086, 49.497473094145505);
+ poly.lineTo(38.636627026664385, 51.036687142232736);
+
+ poly.startPath(39.00920080789793, 62.063425518369016);
+ poly.lineTo(38.604912643136885, 70.0);
+ poly.lineTo(40.71826863485308, 43.60337143116787);
+ poly.lineTo(35.34407570857744, 54.005512477134126);
+ poly.lineTo(39.29611825817084, 22.64634933678729);
+
+ return poly;
+ }
+
+ public Polyline makeNonSimplePolyline() {
+ // This polyline has a short segment
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(10, 0);
+ poly.lineTo(10, 10);
+ poly.lineTo(10, 5);
+ poly.lineTo(-5, 5);
+
+ return poly;
+ }// done
+
+ @Test
+ public void testIsSimpleBasicsPoint() {
+ boolean result;
+ // point is always simple
+ Point pt = new Point();
+ result = simplifyOp.isSimpleAsFeature(pt, sr4326, false, null, null);
+ assertTrue(result);
+ pt.setXY(0, 0);
+ result = simplifyOp.isSimpleAsFeature(pt, sr4326, false, null, null);
+ assertTrue(result);
+ pt.setXY(100000, 10000);
+ result = simplifyOp.isSimpleAsFeature(pt, sr4326, false, null, null);
+ assertTrue(result);
+ }// done
+
+ @Test
+ public void testIsSimpleBasicsEnvelope() {
+ // Envelope is simple, when it's width and height are not degenerate
+ Envelope env = new Envelope();
+ boolean result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null,
+ null); // Empty is simple
+ assertTrue(result);
+ env.setCoords(0, 0, 10, 10);
+ result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null, null);
+ assertTrue(result);
+ // sliver but still simple
+ env.setCoords(0, 0, 0 + sr4326.getTolerance() * 2, 10);
+ result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null, null);
+ assertTrue(result);
+ // sliver and not simple
+ env.setCoords(0, 0, 0 + sr4326.getTolerance() * 0.5, 10);
+ result = simplifyOp.isSimpleAsFeature(env, sr4326, false, null, null);
+ assertTrue(!result);
+ }// done
+
+ @Test
+ public void testIsSimpleBasicsLine() {
+ Line line = new Line();
+ boolean result = simplifyOp.isSimpleAsFeature(line, sr4326, false,
+ null, null);
+ assertTrue(!result);
+
+ line.setStart(new Point(0, 0));
+ // line.setEndXY(0, 0);
+ result = simplifyOp.isSimpleAsFeature(line, sr4326, false, null, null);
+ assertTrue(!result);
+ line.setEnd(new Point(1, 0));
+ result = simplifyOp.isSimpleAsFeature(line, sr4326, false, null, null);
+ assertTrue(result);
+ }// done
+
+ @Test
+ public void testIsSimpleMultiPoint1() {
+ MultiPoint mp = new MultiPoint();
+ boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
+ null);
+ assertTrue(result);// empty is simple
+ result = simplifyOp.isSimpleAsFeature(
+ simplifyOp.execute(mp, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ }// done
+
+ @Test
+ public void testIsSimpleMultiPoint2FarApart() {
+ // Two point test: far apart
+ MultiPoint mp = new MultiPoint();
+ mp.add(20, 10);
+ mp.add(100, 100);
+ boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
+ null);
+ assertTrue(result);
+ result = simplifyOp.isSimpleAsFeature(
+ simplifyOp.execute(mp, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ assertTrue(mp.getPointCount() == 2);
+ }// done
+
+ @Test
+ public void testIsSimpleMultiPointCoincident() {
+ // Two point test: coincident
+ MultiPoint mp = new MultiPoint();
+ mp.add(100, 100);
+ mp.add(100, 100);
+ boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
+ null);
+ assertTrue(!result);
+ MultiPoint mpS;
+ result = simplifyOp.isSimpleAsFeature(
+ mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
+ sr4326, false, null, null);
+ assertTrue(result);
+ assertTrue(mpS.getPointCount() == 1);
+ }// done
+
+ @Test
+ public void testMultiPointSR4326_CR184439() {
+ OperatorFactoryLocal engine = OperatorFactoryLocal.getInstance();
+ OperatorSimplify simpOp = (OperatorSimplify) engine
+ .getOperator(Operator.Type.Simplify);
+ NonSimpleResult nonSimpResult = new NonSimpleResult();
+ nonSimpResult.m_reason = NonSimpleResult.Reason.NotDetermined;
+ MultiPoint multiPoint = new MultiPoint();
+ multiPoint.add(0, 0);
+ multiPoint.add(0, 1);
+ multiPoint.add(0, 0);
+ Boolean multiPointIsSimple = simpOp.isSimpleAsFeature(multiPoint,
+ SpatialReference.create(4326), true, nonSimpResult, null);
+ assertFalse(multiPointIsSimple);
+ assertTrue(nonSimpResult.m_reason == NonSimpleResult.Reason.Clustering);
+ assertTrue(nonSimpResult.m_vertexIndex1 == 0);
+ assertTrue(nonSimpResult.m_vertexIndex2 == 2);
+ }
+
+ @Test
+ public void testIsSimpleMultiPointCloserThanTolerance() {
+ // Two point test: closer than tolerance
+ MultiPoint mp = new MultiPoint();
+ MultiPoint mpS;
+ mp.add(100, 100);
+ mp.add(100, 100 + sr4326.getTolerance() * .5);
+ boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
+ null);
+ assertTrue(result);
+ result = simplifyOp.isSimpleAsFeature(
+ mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
+ sr4326, false, null, null);
+ assertTrue(result);
+ assertTrue(mpS.getPointCount() == 2);
+ }// done
+
+ @Test
+ public void testIsSimpleMultiPointFarApart2() {
+ // 5 point test: far apart
+ MultiPoint mp = new MultiPoint();
+ mp.add(100, 100);
+ mp.add(100, 101);
+ mp.add(101, 101);
+ mp.add(11, 1);
+ mp.add(11, 14);
+ MultiPoint mpS;
+ boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
+ null);
+ assertTrue(result);
+ result = simplifyOp.isSimpleAsFeature(
+ mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
+ sr4326, false, null, null);
+ assertTrue(result);
+ assertTrue(mpS.getPointCount() == 5);
+ }// done
+
+ @Test
+ public void testIsSimpleMultiPoint_coincident2() {
+ // 5 point test: coincident
+ MultiPoint mp = new MultiPoint();
+ mp.add(100, 100);
+ mp.add(100, 101);
+ mp.add(100, 100);
+ mp.add(11, 1);
+ mp.add(11, 14);
+ boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
+ null);
+ assertTrue(!result);
+ MultiPoint mpS;
+ result = simplifyOp.isSimpleAsFeature(
+ mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
+ sr4326, false, null, null);
+ assertTrue(result);
+ assertTrue(mpS.getPointCount() == 4);
+ assertEquals(mpS.getPoint(0).getX(), 100, 1e-7);
+ assertEquals(mpS.getPoint(0).getY(), 100, 1e-7);
+ assertEquals(mpS.getPoint(1).getX(), 100, 1e-7);
+ assertEquals(mpS.getPoint(1).getY(), 101, 1e-7);
+ assertEquals(mpS.getPoint(2).getX(), 11, 1e-7);
+ assertEquals(mpS.getPoint(2).getY(), 1, 1e-7);
+ assertEquals(mpS.getPoint(3).getX(), 11, 1e-7);
+ assertEquals(mpS.getPoint(3).getY(), 14, 1e-7);
+ }// done
+
+ @Test
+ public void testIsSimpleMultiPointCloserThanTolerance2() {
+ // 5 point test: closer than tolerance
+ MultiPoint mp = new MultiPoint();
+ mp.add(100, 100);
+ mp.add(100, 101);
+ mp.add(100, 100 + sr4326.getTolerance() / 2);
+ mp.add(11, 1);
+ mp.add(11, 14);
+ MultiPoint mpS;
+ boolean result = simplifyOp.isSimpleAsFeature(mp, sr4326, false, null,
+ null);
+ assertTrue(result);
+ result = simplifyOp.isSimpleAsFeature(
+ mpS = (MultiPoint) simplifyOp.execute(mp, sr4326, false, null),
+ sr4326, false, null, null);
+ assertTrue(result);
+ assertTrue(mpS.getPointCount() == 5);
+ }// done
+
+ @Test
+ public void testIsSimplePolyline() {
+ Polyline poly = new Polyline();
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);// empty is simple
+ }
+
+ @Test
+ public void testIsSimplePolylineFarApart() {
+ // Two point test: far apart
+ Polyline poly = new Polyline();
+ poly.startPath(20, 10);
+ poly.lineTo(100, 100);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsSimplePolylineCoincident() {
+ // Two point test: coincident
+ Polyline poly = new Polyline();
+ poly.startPath(100, 100);
+ poly.lineTo(100, 100);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ @SuppressWarnings("unused")
+ Polyline polyS;
+ result = simplifyOp.isSimpleAsFeature(
+ polyS = (Polyline) simplifyOp
+ .execute(poly, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsSimplePolylineCloserThanTolerance() {
+ // Two point test: closer than tolerance
+ Polyline poly = new Polyline();
+ poly.startPath(100, 100);
+ poly.lineTo(100, 100 + sr4326.getTolerance() / 2);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ @SuppressWarnings("unused")
+ Polyline polyS;
+ result = simplifyOp.isSimpleAsFeature(
+ polyS = (Polyline) simplifyOp
+ .execute(poly, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsSimplePolylineFarApartSelfOverlap0() {
+ // 3 point test: far apart, self overlapping
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.lineTo(0, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);// TO CONFIRM should be false
+ }
+
+ @Test
+ public void testIsSimplePolylineSelfIntersect() {
+ // 4 point test: far apart, self intersecting
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.lineTo(0, 100);
+ poly.lineTo(100, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);// TO CONFIRM should be false
+ }
+
+ @Test
+ public void testIsSimplePolylineDegenerateSegment() {
+ // 4 point test: degenerate segment
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.lineTo(100, 100 + sr4326.getTolerance() / 2);
+ poly.lineTo(100, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ @SuppressWarnings("unused")
+ Polyline polyS;
+ result = simplifyOp.isSimpleAsFeature(
+ polyS = (Polyline) simplifyOp
+ .execute(poly, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ {
+ Polyline other = new Polyline();
+ other.startPath(0, 0);
+ other.lineTo(100, 100);
+ other.lineTo(100, 0);
+ other.equals(poly);
+ }
+ }
+
+ @Test
+ public void testIsSimplePolylineFarApartSelfOverlap() {
+ // 3 point test: far apart, self overlapping
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.lineTo(0, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);// TO CONFIRM should be false
+ }
+
+ @Test
+ public void testIsSimplePolylineFarApartIntersect() {
+ // 4 point 2 parts test: far apart, intersecting parts
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.startPath(100, 0);
+ poly.lineTo(0, 100);
+
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);// TO CONFIRM should be false
+ }
+
+ @Test
+ public void testIsSimplePolylineFarApartOverlap2() {
+ // 4 point 2 parts test: far apart, overlapping parts. second part
+ // starts where first one ends
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.startPath(100, 100);
+ poly.lineTo(0, 100);
+
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);// TO CONFIRM should be false
+ }
+
+ @Test
+ public void testIsSimplePolylineDegenerateVertical() {
+ // 3 point test: degenerate vertical line
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(new Point(100, 100));
+ poly.lineTo(new Point(100, 100));
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ Polyline polyS;
+ result = simplifyOp.isSimpleAsFeature(
+ polyS = (Polyline) simplifyOp
+ .execute(poly, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ assertTrue(polyS.getPointCount() == 2);
+ }
+
+ @Test
+ public void testIsSimplePolylineEmptyPath() {
+ // TODO: any way to test this?
+ // Empty path
+ // Polyline poly = new Polyline();
+ // assertTrue(poly.isEmpty());
+ // poly.addPath(new Polyline(), 0, true);
+ // assertTrue(poly.isEmpty());
+ // boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ // null, null);
+ // assertTrue(result);
+ }
+
+ @Test
+ public void testIsSimplePolylineSinglePointInPath() {
+ // Single point in path
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.removePoint(0, 1);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ Polyline polyS;
+ result = simplifyOp.isSimpleAsFeature(
+ polyS = (Polyline) simplifyOp
+ .execute(poly, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ assertTrue(polyS.isEmpty());
+ }
+
+ @Test
+ public void testIsSimplePolygon() {
+ Polygon poly = new Polygon();
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);// empty is simple
+ result = simplifyOp.isSimpleAsFeature(
+ simplifyOp.execute(poly, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);// empty is simple
+ }
+
+ @Test
+ public void testIsSimplePolygonEmptyPath() {
+ // TODO:
+ // Empty path
+ // Polygon poly = new Polygon();
+ // poly.addPath(new Polyline(), 0, true);
+ // assertTrue(poly.getPathCount() == 1);
+ // boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ // null,
+ // null);
+ // assertTrue(result);
+ // result = simplifyOp.isSimpleAsFeature(simplifyOp.execute(poly,
+ // sr4326, false, null), sr4326, false, null, null);
+ // assertTrue(result);// empty is simple
+ // assertTrue(poly.getPathCount() == 1);
+ }
+
+ @Test
+ public void testIsSimplePolygonIncomplete1() {
+ // Incomplete polygon 1
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ // poly.removePoint(0, 1);//TO CONFIRM no removePoint method in Java
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonIncomplete2() {
+ // Incomplete polygon 2
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonDegenerateTriangle() {
+ // Degenerate triangle (self overlap)
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.lineTo(0, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonSelfIntersect() {
+ // Self intersection - cracking is needed
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.lineTo(0, 100);
+ poly.lineTo(100, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonRectangleHole() {
+ // Rectangle and rectangular hole that has one segment overlapping
+ // with the with the exterior ring. Cracking is needed.
+ Polygon poly = new Polygon();
+ poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
+ poly.addEnvelope(new Envelope(-100, -100, 100, 50), true);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ poly.reverseAllPaths();
+ result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonRectangleHole2() {
+ // Rectangle and rectangular hole
+ Polygon poly = new Polygon();
+ poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
+ poly.addEnvelope(new Envelope(-100, -50, 100, 50), true);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);
+ poly.reverseAllPaths();
+ result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonSelfIntersectAtVertex() {
+ // Self intersection at vertex
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(50, 50);
+ poly.lineTo(100, 100);
+ poly.lineTo(0, 100);
+ poly.lineTo(50, 50);
+ poly.lineTo(100, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ result = simplifyOp.isSimpleAsFeature(
+ simplifyOp.execute(poly, sr4326, false, null), sr4326, false,
+ null, null);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsSimplePolygon_2EdgesTouchAtVertex() {
+ // No self-intersection, but more than two edges touch at the same
+ // vertex. Simple for ArcGIS, not simple for OGC
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(50, 50);
+ poly.lineTo(0, 100);
+ poly.lineTo(100, 100);
+ poly.lineTo(50, 50);
+ poly.lineTo(100, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsSimplePolygonTriangle() {
+ // Triangle
+ Polygon poly = new Polygon();
+ poly.startPath(0, 0);
+ poly.lineTo(100, 100);
+ poly.lineTo(100, 0);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);
+ poly.reverseAllPaths();
+ result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonRectangle() {
+ // Rectangle
+ Polygon poly = new Polygon();
+ poly.addEnvelope(new Envelope(-200, -100, 100, 200), false);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);
+ poly.reverseAllPaths();
+ result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonRectangleHoleWrongDirection() {
+ // Rectangle and rectangular hole that has wrong direction
+ Polygon poly = new Polygon();
+ poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
+ poly.addEnvelope(new Envelope(-100, -50, 100, 50), false);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(!result);
+ poly.reverseAllPaths();
+ result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygon_2RectanglesSideBySide() {
+ // Two rectangles side by side, simple
+ Polygon poly = new Polygon();
+ poly.addEnvelope(new Envelope(-200, -100, 200, 100), false);
+ poly.addEnvelope(new Envelope(220, -50, 300, 50), false);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);
+ poly.reverseAllPaths();
+ result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testIsSimplePolygonRectangleOneBelow() {
+ // Two rectangles one below another, simple
+ Polygon poly = new Polygon();
+ poly.addEnvelope(new Envelope(50, 50, 100, 100), false);
+ poly.addEnvelope(new Envelope(50, 200, 100, 250), false);
+ boolean result = simplifyOp.isSimpleAsFeature(poly, sr4326, false,
+ null, null);
+ assertTrue(result);
+ poly.reverseAllPaths();
+ result = simplifyOp.isSimpleAsFeature(poly, sr4326, false, null, null);
+ assertTrue(!result);
+ }
+
+ @Test
+ public void testisSimpleOGC() {
+ Polyline poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(10, 0);
+ boolean result = simplifyOpOGC.isSimpleOGC(poly, sr4326, true, null,
+ null);
+ assertTrue(result);
+
+ poly = new Polyline();
+ poly.startPath(0, 0);
+ poly.lineTo(10, 10);
+ poly.lineTo(0, 10);
+ poly.lineTo(10, 0);
+ NonSimpleResult nsr = new NonSimpleResult();
+ result = simplifyOpOGC.isSimpleOGC(poly, sr4326, true, nsr, null);
+ assertTrue(!result);
+ assertTrue(nsr.m_reason == NonSimpleResult.Reason.Cracking);
+
+ MultiPoint mp = new MultiPoint();
+ mp.add(0, 0);
+ mp.add(10, 0);
+ result = simplifyOpOGC.isSimpleOGC(mp, sr4326, true, null, null);
+ assertTrue(result);
+
+ mp = new MultiPoint();
+ mp.add(10, 0);
+ mp.add(10, 0);
+ nsr = new NonSimpleResult();
+ result = simplifyOpOGC.isSimpleOGC(mp, sr4326, true, nsr, null);
+ assertTrue(!result);
+ assertTrue(nsr.m_reason == NonSimpleResult.Reason.Clustering);
+ }
+
+ @Test
+ public void testPolylineIsSimpleForOGC() {
+ OperatorImportFromJson importerJson = (OperatorImportFromJson) factory
+ .getOperator(Operator.Type.ImportFromJson);
+ OperatorSimplify simplify = (OperatorSimplify) factory
+ .getOperator(Operator.Type.Simplify);
+
+ {
+ String s = "{\"paths\":[[[0, 10], [8, 5], [5, 2], [6, 0]]]}";
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(res);
+ }
+ {
+ String s = "{\"paths\":[[[0, 10], [6, 0], [7, 5], [0, 3]]]}";// self
+ // intersection
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(!res);
+ }
+
+ {
+ String s = "{\"paths\":[[[0, 10], [6, 0], [0, 3], [0, 10]]]}"; // closed
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(res);
+ }
+
+ {
+ String s = "{\"paths\":[[[0, 10], [5, 5], [6, 0], [0, 3], [5, 5], [0, 9], [0, 10]]]}"; // closed
+ // with
+ // self
+ // tangent
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(!res);
+ }
+
+ {
+ String s = "{\"paths\":[[[0, 10], [5, 2]], [[5, 2], [6, 0]]]}";// two
+ // paths
+ // connected
+ // at
+ // a
+ // point
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(res);
+ }
+
+ {
+ String s = "{\"paths\":[[[0, 0], [3, 3], [5, 0], [0, 0]], [[0, 10], [3, 3], [10, 10], [0, 10]]]}";// two
+ // closed
+ // rings
+ // touch
+ // at
+ // one
+ // point
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(!res);
+ }
+
+ {
+ String s = "{\"paths\":[[[0, 0], [10, 10]], [[0, 10], [10, 0]]]}";// two
+ // lines
+ // intersect
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(!res);
+ }
+
+ {
+ String s = "{\"paths\":[[[0, 0], [5, 5], [0, 10]], [[10, 10], [5, 5], [10, 0]]]}";// two
+ // paths
+ // share
+ // mid
+ // point.
+ Geometry g = importerJson.execute(Geometry.Type.Unknown,
+ JsonParserReader.createFromString(s)).getGeometry();
+ boolean res = simplifyOpOGC.isSimpleOGC(g, null, true, null, null);
+ assertTrue(!res);
+ }
+
+ }
+
+ @Test
+ public void testFillRule() {
+ //self intersecting star shape
+ MapGeometry mg = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, "{\"rings\":[[[0,0], [5,10], [10, 0], [0, 7], [10, 7], [0, 0]]]}");
+ Polygon poly = (Polygon)mg.getGeometry();
+ assertTrue(poly.getFillRule() == Polygon.FillRule.enumFillRuleOddEven);
+ poly.setFillRule(Polygon.FillRule.enumFillRuleWinding);
+ assertTrue(poly.getFillRule() == Polygon.FillRule.enumFillRuleWinding);
+ Geometry simpleResult = OperatorSimplify.local().execute(poly, null, true, null);
+ assertTrue(((Polygon)simpleResult).getFillRule() == Polygon.FillRule.enumFillRuleOddEven);
+ //solid start without holes:
+ MapGeometry mg1 = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, "{\"rings\":[[[0,0],[2.5925925925925926,5.185185185185185],[0,7],[3.5,7],[5,10],[6.5,7],[10,7],[7.407407407407407,5.185185185185185],[10,0],[5,3.5],[0,0]]]}");
+ boolean equals = OperatorEquals.local().execute(mg1.getGeometry(), simpleResult, null, null);
+ assertTrue(equals);
+ }
+
+}
diff --git a/src/test/java/com/esri/core/geometry/TestSpatialReference.java b/src/test/java/com/esri/core/geometry/TestSpatialReference.java
new file mode 100644
index 00000000..c002f977
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestSpatialReference.java
@@ -0,0 +1,49 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class TestSpatialReference extends TestCase {
+ @Test
+ public void testEquals() {
+ String wktext1 = "GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]]";
+ String wktext2 = "PROJCS[\"WGS_1984_Web_Mercator_Auxiliary_Sphere\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator_Auxiliary_Sphere\"],PARAMETER[\"False_Easting\",0.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],PARAMETER[\"Standard_Parallel_1\",0.0],PARAMETER[\"Auxiliary_Sphere_Type\",0.0],UNIT[\"Meter\",1.0]]";
+
+ SpatialReference a1 = SpatialReference.create(wktext1);
+ SpatialReference b = SpatialReference.create(wktext2);
+ SpatialReference a2 = SpatialReference.create(wktext1);
+
+ assertTrue(a1.equals(a1));
+ assertTrue(b.equals(b));
+
+ assertTrue(a1.equals(a2));
+
+ assertFalse(a1.equals(b));
+ assertFalse(b.equals(a1));
+ }
+}
+
diff --git a/unittest/com/esri/core/geometry/TestTouch.java b/src/test/java/com/esri/core/geometry/TestTouch.java
similarity index 78%
rename from unittest/com/esri/core/geometry/TestTouch.java
rename to src/test/java/com/esri/core/geometry/TestTouch.java
index c12d3999..8be45c11 100644
--- a/unittest/com/esri/core/geometry/TestTouch.java
+++ b/src/test/java/com/esri/core/geometry/TestTouch.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
@@ -35,15 +59,6 @@ public void testTouchOnPointAndPolyline() {
isTouched2 = false;
}
assertEquals(isTouched && isTouched2, true);
-
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- pl,
- baseGeom,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -67,15 +82,6 @@ public void testTouchOnPointAndPolygon() {
isTouched2 = false;
}
assertEquals(isTouched && isTouched2, true);
-
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- pg,
- baseGeom,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -139,14 +145,6 @@ public void testTouchesOnPolylines() {
isTouched = false;
}
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- compPl,
- basePl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -175,14 +173,6 @@ public void testTouchesOnPolylineAndPolygon() {
}
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- compPl,
- basePl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -205,14 +195,6 @@ public void testTouchOnEnvelopes() {
}
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- env,
- env2,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -238,14 +220,6 @@ public void testTouchesOnPolylineAndEnvelope() {
}
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- env,
- basePl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -270,14 +244,6 @@ public void testTouchesOnPolygonAndEnvelope() {
}
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- env,
- basePl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -297,14 +263,6 @@ public void testTouchesOnPointAndEnvelope() {
}
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- p,
- env,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -325,14 +283,6 @@ public void testRelationTouch() {
// "G1 TOUCH G2");
assertEquals(isTouched, false);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- compPl,
- basePl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -356,17 +306,6 @@ public void testTouchesBetweenPointAndLine() {
boolean isTouched = GeometryEngine.touches(p, compPl, sr);
assertTrue(!isTouched);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- compPl,
- p,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
- // We do not treat polyline that is not explicitly closed as closed.
- // Keep the case to demonstrate the difference between ArcObjects and
- // Borg here.
}
@Test
@@ -394,14 +333,6 @@ public void testTouchesBetweenPolylines() {
boolean isTouched = GeometryEngine.touches(pl, compPl, sr);
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- compPl,
- pl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -433,14 +364,6 @@ public void testTouchesBetweenPolylineAndPolygon() {
boolean isTouched = GeometryEngine.touches(pl, compPg, sr);
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- compPg,
- pl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
@@ -507,14 +430,6 @@ public void testTouchesBetweenMultipartPolygons2() {
boolean isTouched = GeometryEngine.touches(pl, compPl, sr);
assertEquals(isTouched, true);
- boolean isTouchedFromRest = GeometryUtils
- .isRelationTrue(
- compPl,
- pl,
- sr,
- GeometryUtils.SpatialRelationType.esriGeometryRelationTouch,
- "");
- assertTrue(isTouchedFromRest == isTouched);
}
@Test
diff --git a/unittest/com/esri/core/geometry/TestTreap.java b/src/test/java/com/esri/core/geometry/TestTreap.java
similarity index 70%
rename from unittest/com/esri/core/geometry/TestTreap.java
rename to src/test/java/com/esri/core/geometry/TestTreap.java
index 3bd20606..e1f2b5b5 100644
--- a/unittest/com/esri/core/geometry/TestTreap.java
+++ b/src/test/java/com/esri/core/geometry/TestTreap.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import junit.framework.TestCase;
diff --git a/src/test/java/com/esri/core/geometry/TestUnion.java b/src/test/java/com/esri/core/geometry/TestUnion.java
new file mode 100644
index 00000000..77032413
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestUnion.java
@@ -0,0 +1,180 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class TestUnion extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public static void testUnion() {
+ Envelope env1 = new Envelope(10, 10, 30, 50);
+ Envelope env2 = new Envelope(30, 10, 60, 50);
+ Geometry[] geomArray = new Geometry[] { env1, env2 };
+ SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(
+ geomArray);
+ OperatorUnion union = (OperatorUnion) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.Union);
+
+ SpatialReference sr = SpatialReference.create(4326);
+
+ GeometryCursor outputCursor = union.execute(inputGeometries, sr, null);
+ Geometry result = outputCursor.next();
+
+ MultiPath path = (MultiPath)result;
+ assertEquals(1, path.getPathCount());
+ assertEquals(6, path.getPathEnd(0));
+ assertEquals(new Point2D(10, 10), path.getXY(0));
+ assertEquals(new Point2D(10, 50), path.getXY(1));
+ assertEquals(new Point2D(30, 50), path.getXY(2));
+ assertEquals(new Point2D(60, 50), path.getXY(3));
+ assertEquals(new Point2D(60, 10), path.getXY(4));
+ assertEquals(new Point2D(30, 10), path.getXY(5));
+ }
+
+ @Test
+ public static void testUnionDistinctGeometries() {
+ Envelope env = new Envelope(1, 5, 3, 10);
+
+ Polygon polygon = new Polygon();
+ polygon.startPath(new Point(4, 3));
+ polygon.lineTo(new Point(7, 6));
+ polygon.lineTo(new Point(6, 8));
+ polygon.lineTo(new Point(4, 3));
+
+ Geometry[] geomArray = new Geometry[] { env, polygon };
+ SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(
+ geomArray);
+ OperatorUnion union = (OperatorUnion) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.Union);
+ SpatialReference sr = SpatialReference.create(4326);
+
+ GeometryCursor outputCursor = union.execute(inputGeometries, sr, null);
+ Geometry result = outputCursor.next();
+
+ MultiPath path = (MultiPath)result;
+ assertEquals(2, path.getPathCount());
+
+ assertEquals(3, path.getPathEnd(0));
+ assertEquals(7, path.getPathEnd(1));
+ // from polygon
+ assertEquals(new Point2D(4, 3), path.getXY(0));
+ assertEquals(new Point2D(6, 8), path.getXY(1));
+ assertEquals(new Point2D(7, 6), path.getXY(2));
+ // from envelope
+ assertEquals(new Point2D(1, 5), path.getXY(3));
+ assertEquals(new Point2D(1, 10), path.getXY(4));
+ assertEquals(new Point2D(3, 10), path.getXY(5));
+ assertEquals(new Point2D(3, 5), path.getXY(6));
+ }
+
+ @Test
+ public static void testUnionCoincidentPolygons() {
+ Polygon polygon1 = new Polygon();
+ polygon1.startPath(new Point(3, 2));
+ polygon1.lineTo(new Point(1, 2));
+ polygon1.lineTo(new Point(1, 4));
+ polygon1.lineTo(new Point(3, 4));
+ polygon1.lineTo(new Point(3, 2));
+
+ Polygon polygon2 = new Polygon();
+ polygon2.startPath(new Point(1, 2));
+ polygon2.lineTo(new Point(1, 4));
+ polygon2.lineTo(new Point(3, 4));
+ polygon2.lineTo(new Point(3, 2));
+ polygon2.lineTo(new Point(1, 2));
+
+ Geometry[] geomArray = new Geometry[] { polygon1, polygon2 };
+ SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(
+ geomArray);
+ OperatorUnion union = (OperatorUnion) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.Union);
+ SpatialReference sr = SpatialReference.create(4326);
+
+ GeometryCursor outputCursor = union.execute(inputGeometries, sr, null);
+ Geometry result = outputCursor.next();
+
+ MultiPath path = (MultiPath)result;
+ assertEquals(1, path.getPathCount());
+ assertEquals(4, path.getPathEnd(0));
+ assertEquals(new Point2D(1, 2), path.getXY(0));
+ assertEquals(new Point2D(1, 4), path.getXY(1));
+ assertEquals(new Point2D(3, 4), path.getXY(2));
+ assertEquals(new Point2D(3, 2), path.getXY(3));
+ }
+
+ @Test
+ public static void testUnionCoincidentPolygonsWithReverseWinding() {
+ // Input polygons have CCW winding, result is always CW
+ Polygon polygon1 = new Polygon();
+ polygon1.startPath(new Point(3, 2));
+ polygon1.lineTo(new Point(3, 4));
+ polygon1.lineTo(new Point(1, 4));
+ polygon1.lineTo(new Point(1, 2));
+ polygon1.lineTo(new Point(3, 2));
+
+ Polygon polygon2 = new Polygon();
+ polygon2.startPath(new Point(1, 2));
+ polygon2.lineTo(new Point(3, 2));
+ polygon2.lineTo(new Point(3, 4));
+ polygon2.lineTo(new Point(1, 4));
+ polygon2.lineTo(new Point(1, 2));
+
+ Polygon expectedPolygon = new Polygon();
+ expectedPolygon.startPath(new Point(1, 2));
+ expectedPolygon.lineTo(new Point(1, 4));
+ expectedPolygon.lineTo(new Point(3, 4));
+ expectedPolygon.lineTo(new Point(3, 2));
+ expectedPolygon.lineTo(new Point(1, 2));
+
+ Geometry[] geomArray = new Geometry[] { polygon1, polygon2 };
+ SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(
+ geomArray);
+ OperatorUnion union = (OperatorUnion) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.Union);
+ SpatialReference sr = SpatialReference.create(4326);
+
+ GeometryCursor outputCursor = union.execute(inputGeometries, sr, null);
+ Geometry result = outputCursor.next();
+
+ MultiPath path = (MultiPath)result;
+ assertEquals(1, path.getPathCount());
+ assertEquals(4, path.getPathEnd(0));
+ assertEquals(new Point2D(1, 2), path.getXY(0));
+ assertEquals(new Point2D(1, 4), path.getXY(1));
+ assertEquals(new Point2D(3, 4), path.getXY(2));
+ assertEquals(new Point2D(3, 2), path.getXY(3));
+ }
+}
diff --git a/src/test/java/com/esri/core/geometry/TestWKBSupport.java b/src/test/java/com/esri/core/geometry/TestWKBSupport.java
new file mode 100644
index 00000000..dfbaba16
--- /dev/null
+++ b/src/test/java/com/esri/core/geometry/TestWKBSupport.java
@@ -0,0 +1,119 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
+package com.esri.core.geometry;
+
+import com.esri.core.geometry.ogc.OGCGeometry;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+//import com.vividsolutions.jts.io.WKBReader;
+
+public class TestWKBSupport extends TestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ public void testWKB() {
+ // JSON -> GEOM -> WKB
+
+ String strPolygon1 = "{\"xmin\":-1.1663479012889031E7,\"ymin\":4919777.494405342,\"xmax\":-1.1658587043078788E7,\"ymax\":4924669.464215587,\"spatialReference\":{\"wkid\":102100}}";
+ // String strPolygon1 =
+ // "{\"rings\":[[[-119.152450421001,38.4118009590513],[-119.318825070203,38.5271086243914],[-119.575687062955,38.7029101298904],[-119.889341639399,38.9222515603984],[-119.995254694357,38.9941061536377],[-119.995150114198,39.0634913594691],[-119.994541258334,39.1061318056708],[-119.995527335641,39.1587132866355],[-119.995304181493,39.3115454332125],[-119.996011479298,39.4435009764511],[-119.996165311172,39.7206108077274],[-119.996324660047,41.1775662656441],[-119.993459369715,41.9892049531992],[-119.351692186077,41.9888529749781],[-119.3109421304,41.9891353872811],[-118.185316829038,41.9966370981387],[-117.018864363596,41.9947941808341],[-116.992313337997,41.9947945094663],[-115.947544658193,41.9945994628997],[-115.024862911148,41.996506455953],[-114.269471632824,41.9959242345073],[-114.039072662345,41.9953908974688],[-114.038151248682,40.9976868405942],[-114.038108189376,40.1110466529553],[-114.039844684228,39.9087788600023],[-114.040105338584,39.5386849268845],[-114.044267501155,38.6789958815881],[-114.045090206153,38.5710950539539],[-114.047272999176,38.1376524399918],[-114.047260595159,37.5984784866001],[-114.043939384154,36.9965379371421],[-114.043716435713,36.8418489458647],[-114.037392074194,36.2160228969702],[-114.045105557286,36.1939778840226],[-114.107775185788,36.1210907070504],[-114.12902308363,36.041730493896],[-114.206768869568,36.0172554164834],[-114.233472615347,36.0183310595897],[-114.307587598189,36.0622330993643],[-114.303857056018,36.0871084040611],[-114.316095374696,36.1114380366653],[-114.344233941709,36.1374802520568],[-114.380803116644,36.1509912717765],[-114.443945697733,36.1210532841897],[-114.466613475422,36.1247112590539],[-114.530573568745,36.1550902046725],[-114.598935242024,36.1383354528834],[-114.621610747198,36.1419666834504],[-114.712761724737,36.1051810523675],[-114.728150311069,36.0859627711604],[-114.728966012834,36.0587530361083],[-114.717673567756,36.0367580437018],[-114.736212493583,35.9876483502758],[-114.699275906446,35.9116119537412],[-114.661600122152,35.8804735854242],[-114.662462095522,35.8709599070091],[-114.689867343369,35.8474424944766],[-114.682739704595,35.7647034175617],[-114.688820027649,35.7325957399896],[-114.665091345861,35.6930994107107],[-114.668486064922,35.6563989882404],[-114.654065925137,35.6465840800053],[-114.6398667219,35.6113485698329],[-114.653134321223,35.5848331056108],[-114.649792053474,35.5466373866597],[-114.672215155693,35.5157541647721],[-114.645396168451,35.4507608261463],[-114.589584275424,35.3583787306827],[-114.587889840369,35.30476812919],[-114.559583045727,35.2201828714608],[-114.561039964054,35.1743461616313],[-114.572255261053,35.1400677445931],[-114.582616239058,35.1325604694085],[-114.626440825485,35.1339067529872],[-114.6359090842,35.1186557767895],[-114.595631971944,35.0760579746697],[-114.633779872695,35.0418633504303],[-114.621068606189,34.9989144286133],[-115.626197382816,35.7956983148418],[-115.88576934392,36.0012259572723],[-117.160423771838,36.9595941441767],[-117.838686423167,37.457298239715],[-118.417419755966,37.8866767486211],[-119.152450421001,38.4118009590513]]], \"spatialReference\":{\"wkid\":4326}}";
+
+ MapGeometry mapGeom = GeometryEngine.jsonToGeometry(strPolygon1);
+ Geometry geom = mapGeom.getGeometry();
+ OperatorExportToWkb operatorExport = (OperatorExportToWkb) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.ExportToWkb);
+ ByteBuffer byteBuffer = operatorExport.execute(0, geom, null);
+ byte[] wkb = byteBuffer.array();
+
+ // WKB -> GEOM -> JSON
+ OperatorImportFromWkb operatorImport = (OperatorImportFromWkb) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ geom = operatorImport.execute(0, Geometry.Type.Polygon,
+ ByteBuffer.wrap(wkb), null);
+ // geom = operatorImport.execute(0, Geometry.Type.Polygon,
+ // byteBuffer);
+ String outputPolygon1 = GeometryEngine.geometryToJson(-1, geom);
+ }
+
+ @Test
+ public void testWKB2() throws Exception {
+ // JSON -> GEOM -> WKB
+
+ // String strPolygon1 =
+ // "{\"xmin\":-1.16605115291E7,\"ymin\":4925189.941699997,\"xmax\":-1.16567772126E7,\"ymax\":4928658.771399997,\"spatialReference\":{\"wkid\":102100}}";
+ String strPolygon1 = "{\"rings\" : [ [ [-1.16605115291E7,4925189.941699997], [-1.16567772126E7,4925189.941699997], [-1.16567772126E7,4928658.771399997], [-1.16605115291E7,4928658.771399997], [-1.16605115291E7,4925189.941699997] ] ], \"spatialReference\" : {\"wkid\" : 102100}}";
+
+ MapGeometry mapGeom = GeometryEngine.jsonToGeometry(strPolygon1);
+ Geometry geom = mapGeom.getGeometry();
+
+ // simplifying geom
+ OperatorSimplify operatorSimplify = (OperatorSimplify) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.Simplify);
+ SpatialReference sr = SpatialReference.create(102100);
+ geom = operatorSimplify.execute(geom, sr, true, null);
+
+ OperatorExportToWkb operatorExport = (OperatorExportToWkb) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.ExportToWkb);
+ ByteBuffer byteBuffer = operatorExport.execute(0, geom, null);
+ byte[] wkb = byteBuffer.array();
+
+ // // checking WKB correctness
+ // WKBReader jtsReader = new WKBReader();
+ // com.vividsolutions.jts.geom.Geometry jtsGeom = jtsReader.read(wkb);
+ // System.out.println("jtsGeom = " + jtsGeom);
+
+ // WKB -> GEOM -> JSON
+ OperatorImportFromWkb operatorImport = (OperatorImportFromWkb) OperatorFactoryLocal
+ .getInstance().getOperator(Operator.Type.ImportFromWkb);
+ geom = operatorImport.execute(0, Geometry.Type.Polygon,
+ ByteBuffer.wrap(wkb), null);
+ assertTrue(!geom.isEmpty());
+ // geom = operatorImport.execute(0, Geometry.Type.Polygon, byteBuffer);
+ // String outputPolygon1 = GeometryEngine.geometryToJson(-1, geom);
+ // System.out.println(strPolygon1);
+ // System.out.println(outputPolygon1);
+
+ }
+
+ @Test
+ public void testWKB3() throws Exception {
+ String multiPointWKT = "MULTIPOINT ZM(10 40 1 23, 40 30 2 45)";
+ OGCGeometry geometry = OGCGeometry.fromText(multiPointWKT);
+ ByteBuffer byteBuffer = geometry.asBinary();
+ OGCGeometry geomFromBinary = OGCGeometry.fromBinary(byteBuffer);
+ assertTrue(geometry.Equals(geomFromBinary));
+ }
+}
diff --git a/unittest/com/esri/core/geometry/TestWkbImportOnPostgresST.java b/src/test/java/com/esri/core/geometry/TestWkbImportOnPostgresST.java
similarity index 65%
rename from unittest/com/esri/core/geometry/TestWkbImportOnPostgresST.java
rename to src/test/java/com/esri/core/geometry/TestWkbImportOnPostgresST.java
index ccac6c5f..95c55d2b 100644
--- a/unittest/com/esri/core/geometry/TestWkbImportOnPostgresST.java
+++ b/src/test/java/com/esri/core/geometry/TestWkbImportOnPostgresST.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import java.nio.ByteBuffer;
diff --git a/src/com/esri/core/geometry/OperatorExportToJson.java b/src/test/java/com/esri/core/geometry/TestWkid.java
similarity index 50%
rename from src/com/esri/core/geometry/OperatorExportToJson.java
rename to src/test/java/com/esri/core/geometry/TestWkid.java
index 8bf1240e..9bac7c5b 100644
--- a/src/com/esri/core/geometry/OperatorExportToJson.java
+++ b/src/test/java/com/esri/core/geometry/TestWkid.java
@@ -1,5 +1,5 @@
/*
- Copyright 1995-2013 Esri
+ Copyright 1995-2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,37 +21,36 @@
email: contracts@esri.com
*/
+
package com.esri.core.geometry;
-import com.esri.core.geometry.Operator.Type;
+import static org.junit.Assert.*;
+import junit.framework.TestCase;
-/**
- *Export to JSON format.
- */
-public abstract class OperatorExportToJson extends Operator {
- @Override
- public Type getType() {
- return Type.ExportToJson;
- }
+import org.junit.Test;
- /**
- * Performs the ExportToJson operation
- *
- * @return Returns a JsonCursor.
- */
- abstract JsonCursor execute(SpatialReference spatialReference,
- GeometryCursor geometryCursor);
-
- /**
- *Performs the ExportToJson operation
- *@return Returns a String.
- */
- public abstract String execute(SpatialReference spatialReference,
- Geometry geometry);
-
- public static OperatorExportToJson local() {
- return (OperatorExportToJson) OperatorFactoryLocal.getInstance()
- .getOperator(Type.ExportToJson);
+public class TestWkid extends TestCase {
+ @Test
+ public void test() {
+ SpatialReference sr = SpatialReference.create(102100);
+ assertTrue(sr.getID() == 102100);
+ assertTrue(sr.getLatestID() == 3857);
+ assertTrue(sr.getOldID() == 102100);
+ assertTrue(sr.getTolerance() == 0.001);
+
+ SpatialReference sr84 = SpatialReference.create(4326);
+ double tol84 = sr84.getTolerance();
+ assertTrue(Math.abs(tol84 - 1e-8) < 1e-8 * 1e-8);
}
+
+ @Test
+ public void test_80() {
+ SpatialReference sr = SpatialReference.create(3857);
+ assertTrue(sr.getID() == 3857);
+ assertTrue(sr.getLatestID() == 3857);
+ assertTrue(sr.getOldID() == 102100);
+ assertTrue(sr.getTolerance() == 0.001);
+ }
+
}
diff --git a/unittest/com/esri/core/geometry/TestWktParser.java b/src/test/java/com/esri/core/geometry/TestWktParser.java
similarity index 97%
rename from unittest/com/esri/core/geometry/TestWktParser.java
rename to src/test/java/com/esri/core/geometry/TestWktParser.java
index 9949e5a3..71ce5b1d 100644
--- a/unittest/com/esri/core/geometry/TestWktParser.java
+++ b/src/test/java/com/esri/core/geometry/TestWktParser.java
@@ -1,3 +1,27 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
import static org.junit.Assert.*;
@@ -7,6 +31,7 @@
public class TestWktParser extends TestCase {
+ @Test
public void testGeometryCollection() {
String s = " geometrycollection emPty ";
WktParser wktParser = new WktParser();
@@ -136,6 +161,7 @@ public void testGeometryCollection() {
assertTrue(currentToken == WktParser.WktToken.not_available);
}
+ @Test
public void testMultiPolygon() {
String s = " MultIPolYgOn emPty ";
WktParser wktParser = new WktParser();
@@ -413,6 +439,7 @@ public void testMultiPolygon() {
assertTrue(currentToken == WktParser.WktToken.not_available);
}
+ @Test
public void testMultiLineString() {
String s = " MultiLineString emPty ";
WktParser wktParser = new WktParser();
@@ -623,6 +650,7 @@ public void testMultiLineString() {
assertTrue(currentToken == WktParser.WktToken.not_available);
}
+ @Test
public void testMultiPoint() {
String s = " MultipoInt emPty ";
WktParser wktParser = new WktParser();
@@ -758,6 +786,7 @@ public void testMultiPoint() {
assertTrue(currentToken == WktParser.WktToken.not_available);
}
+ @Test
public void testPolygon() {
String s = " Polygon emPty ";
WktParser wktParser = new WktParser();
@@ -968,6 +997,7 @@ public void testPolygon() {
assertTrue(currentToken == WktParser.WktToken.not_available);
}
+ @Test
public void testLineString() {
String s = " LineString emPty ";
WktParser wktParser = new WktParser();
@@ -1022,6 +1052,7 @@ public void testLineString() {
assertTrue(currentToken == WktParser.WktToken.not_available);
}
+ @Test
public void testPoint() {
String s = " PoInT emPty ";
WktParser wktParser = new WktParser();
diff --git a/unittest/com/esri/core/geometry/Utils.java b/src/test/java/com/esri/core/geometry/Utils.java
similarity index 75%
rename from unittest/com/esri/core/geometry/Utils.java
rename to src/test/java/com/esri/core/geometry/Utils.java
index a984cfc5..d9923281 100644
--- a/unittest/com/esri/core/geometry/Utils.java
+++ b/src/test/java/com/esri/core/geometry/Utils.java
@@ -1,7 +1,33 @@
+/*
+ Copyright 1995-2017 Esri
+
+ Licensed 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.
+
+ For additional information, contact:
+ Environmental Systems Research Institute, Inc.
+ Attn: Contracts Dept
+ 380 New York Street
+ Redlands, California, USA 92373
+
+ email: contracts@esri.com
+ */
+
package com.esri.core.geometry;
public class Utils {
static void showProjectedGeometryInfo(MapGeometry mapGeom) {
+ return;
+ /*
System.out.println("\n");
MapGeometry geom = mapGeom;
int wkid = geom.getSpatialReference() != null ? geom
@@ -66,7 +92,7 @@ static void showProjectedGeometryInfo(MapGeometry mapGeom) {
}
System.out.println("wkid: " + wkid);
- }
+ }*/
}
diff --git a/unittest/com/esri/core/geometry/savedAngularUnit.txt b/src/test/resources/com/esri/core/geometry/savedAngularUnit.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedAngularUnit.txt
rename to src/test/resources/com/esri/core/geometry/savedAngularUnit.txt
diff --git a/unittest/com/esri/core/geometry/savedAreaUnit.txt b/src/test/resources/com/esri/core/geometry/savedAreaUnit.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedAreaUnit.txt
rename to src/test/resources/com/esri/core/geometry/savedAreaUnit.txt
diff --git a/unittest/com/esri/core/geometry/savedEnvelope.txt b/src/test/resources/com/esri/core/geometry/savedEnvelope.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedEnvelope.txt
rename to src/test/resources/com/esri/core/geometry/savedEnvelope.txt
diff --git a/src/test/resources/com/esri/core/geometry/savedEnvelope1.txt b/src/test/resources/com/esri/core/geometry/savedEnvelope1.txt
new file mode 100644
index 00000000..5f6ee18b
Binary files /dev/null and b/src/test/resources/com/esri/core/geometry/savedEnvelope1.txt differ
diff --git a/src/test/resources/com/esri/core/geometry/savedEnvelope2D.txt b/src/test/resources/com/esri/core/geometry/savedEnvelope2D.txt
new file mode 100644
index 00000000..354682bc
Binary files /dev/null and b/src/test/resources/com/esri/core/geometry/savedEnvelope2D.txt differ
diff --git a/unittest/com/esri/core/geometry/savedLinearUnit.txt b/src/test/resources/com/esri/core/geometry/savedLinearUnit.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedLinearUnit.txt
rename to src/test/resources/com/esri/core/geometry/savedLinearUnit.txt
diff --git a/unittest/com/esri/core/geometry/savedMultiPoint.txt b/src/test/resources/com/esri/core/geometry/savedMultiPoint.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedMultiPoint.txt
rename to src/test/resources/com/esri/core/geometry/savedMultiPoint.txt
diff --git a/src/test/resources/com/esri/core/geometry/savedMultiPoint1.txt b/src/test/resources/com/esri/core/geometry/savedMultiPoint1.txt
new file mode 100644
index 00000000..e38260f2
Binary files /dev/null and b/src/test/resources/com/esri/core/geometry/savedMultiPoint1.txt differ
diff --git a/unittest/com/esri/core/geometry/savedPoint.txt b/src/test/resources/com/esri/core/geometry/savedPoint.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedPoint.txt
rename to src/test/resources/com/esri/core/geometry/savedPoint.txt
diff --git a/src/test/resources/com/esri/core/geometry/savedPoint1.txt b/src/test/resources/com/esri/core/geometry/savedPoint1.txt
new file mode 100644
index 00000000..f9efdbe5
Binary files /dev/null and b/src/test/resources/com/esri/core/geometry/savedPoint1.txt differ
diff --git a/unittest/com/esri/core/geometry/savedPolygon.txt b/src/test/resources/com/esri/core/geometry/savedPolygon.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedPolygon.txt
rename to src/test/resources/com/esri/core/geometry/savedPolygon.txt
diff --git a/src/test/resources/com/esri/core/geometry/savedPolygon1.txt b/src/test/resources/com/esri/core/geometry/savedPolygon1.txt
new file mode 100644
index 00000000..1fd9c105
Binary files /dev/null and b/src/test/resources/com/esri/core/geometry/savedPolygon1.txt differ
diff --git a/unittest/com/esri/core/geometry/savedPolyline.txt b/src/test/resources/com/esri/core/geometry/savedPolyline.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedPolyline.txt
rename to src/test/resources/com/esri/core/geometry/savedPolyline.txt
diff --git a/src/test/resources/com/esri/core/geometry/savedPolyline1.txt b/src/test/resources/com/esri/core/geometry/savedPolyline1.txt
new file mode 100644
index 00000000..a5624471
Binary files /dev/null and b/src/test/resources/com/esri/core/geometry/savedPolyline1.txt differ
diff --git a/unittest/com/esri/core/geometry/savedProjectionTransformation.txt b/src/test/resources/com/esri/core/geometry/savedProjectionTransformation.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedProjectionTransformation.txt
rename to src/test/resources/com/esri/core/geometry/savedProjectionTransformation.txt
diff --git a/unittest/com/esri/core/geometry/savedSpatialReference.txt b/src/test/resources/com/esri/core/geometry/savedSpatialReference.txt
similarity index 100%
rename from unittest/com/esri/core/geometry/savedSpatialReference.txt
rename to src/test/resources/com/esri/core/geometry/savedSpatialReference.txt
diff --git a/unittest/com/esri/core/geometry/GeometryUtils.java b/unittest/com/esri/core/geometry/GeometryUtils.java
deleted file mode 100644
index cddf9957..00000000
--- a/unittest/com/esri/core/geometry/GeometryUtils.java
+++ /dev/null
@@ -1,259 +0,0 @@
-package com.esri.core.geometry;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.net.URI;
-import java.util.Scanner;
-
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.UriBuilder;
-
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParser;
-
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
-import com.sun.jersey.api.representation.Form;
-
-public class GeometryUtils {
- static WebResource service4Proj;
- static String url4Proj = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer/project";
- static WebResource service4Simplify;
- static String url4Simplify = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer/simplify";
- static WebResource service4Relation;
- static String url4Relation = "http://sampleserver1.arcgisonline.com/arcgis/rest/services/Geometry/GeometryServer/relation";
-
- static {
- ClientConfig config = new DefaultClientConfig();
- Client client = Client.create(config);
- service4Proj = client.resource(getBaseURI4Proj());
- service4Simplify = client.resource(getBaseURI4Simplify());
- service4Relation = client.resource(url4Relation);
- }
-
- private static URI getBaseURI4Proj() {
- return UriBuilder.fromUri(url4Proj).build();
- }
-
- private static URI getBaseURI4Simplify() {
- return UriBuilder.fromUri(url4Simplify).build();
- }
-
- public static Geometry getGeometryForProjectFromRestWS(int srIn, int srOut,
- Geometry geomIn) {
- String jsonStr4Geom = GeometryEngine.geometryToJson(srIn, geomIn);
- String jsonStrNew = "{\"geometryType\":\"" + getGeometryType(geomIn)
- + "\",\"geometries\":[" + jsonStr4Geom + "]}";
-
- Form f = new Form();
- f.add("inSR", srIn);
- f.add("outSR", srOut);
- f.add("geometries", jsonStrNew);
- f.add("f", "json");
-
- ClientResponse response = service4Proj.type(
- MediaType.APPLICATION_FORM_URLENCODED).post(
- ClientResponse.class, f);
- @SuppressWarnings("unused")
- boolean isOK = response.getClientResponseStatus() == ClientResponse.Status.OK;
- Object obj = response.getEntity(String.class);
- String jsonStr = obj.toString();
- int idx2 = jsonStr.lastIndexOf("]");
- int idx1 = jsonStr.indexOf("[");
- if (idx1 == -1 || idx2 == -1)
- return null;
- String jsonStrGeom = jsonStr.substring(idx1 + 1, idx2);
- Geometry geometryObj = getGeometryFromJSon(jsonStrGeom);
- return geometryObj;
- }
-
- public static Geometry getGeometryForSimplifyFromRestWS(int sr,
- Geometry geomIn) {
- String jsonStr4Geom = GeometryEngine.geometryToJson(
- SpatialReference.create(sr), geomIn);
- String jsonStrNew = "{\"geometryType\":\"" + getGeometryType(geomIn)
- + "\",\"geometries\":[" + jsonStr4Geom + "]}";
-
- Form f = new Form();
- f.add("sr", sr);
- f.add("geometries", jsonStrNew);
- f.add("f", "json");
-
- ClientResponse response = service4Simplify.type(
- MediaType.APPLICATION_FORM_URLENCODED).post(
- ClientResponse.class, f);
- @SuppressWarnings("unused")
- boolean isOK = response.getClientResponseStatus() == ClientResponse.Status.OK;
- Object obj = response.getEntity(String.class);
- String jsonStr = obj.toString();
- int idx2 = jsonStr.lastIndexOf("]");
- int idx1 = jsonStr.indexOf("[");
- if (idx1 == -1 || idx2 == -1)
- return null;
- String jsonStrGeom = jsonStr.substring(idx1 + 1, idx2);
- Geometry geometryObj = getGeometryFromJSon(jsonStrGeom);
- return geometryObj;
- }
-
- static String getGeometryType(Geometry geomIn) {
- // there are five types: esriGeometryPoint
- // esriGeometryMultipoint
- // esriGeometryPolyline
- // esriGeometryPolygon
- // esriGeometryEnvelope
- if (geomIn instanceof Point)
- return "esriGeometryPoint";
- if (geomIn instanceof MultiPoint)
- return "esriGeometryMultipoint";
- if (geomIn instanceof Polyline)
- return "esriGeometryPolyline";
- if (geomIn instanceof Polygon)
- return "esriGeometryPolygon";
- if (geomIn instanceof Envelope)
- return "esriGeometryEnvelope";
- else
- return null;
- }
-
- static Geometry getGeometryFromJSon(String jsonStr) {
- JsonFactory jf = new JsonFactory();
-
- try {
- JsonParser jp = jf.createJsonParser(jsonStr);
- jp.nextToken();
- Geometry geom = GeometryEngine.jsonToGeometry(jp).getGeometry();
- return geom;
- } catch (Exception ex) {
- return null;
- }
- }
-
- public static void testMultiplePath(MultiPath mp1, MultiPath mp2) {
- int count1 = mp1.getPointCount();
- int count2 = mp2.getPointCount();
-
- System.out.println("From Rest vertices count: " + count1);
- System.out.println("From Borg count: " + count2);
- // Assert.assertTrue(count1==count2);
-
- int len = mp1.getPointCount();
-
- for (int i = 0; i < len; i++) {
- Point p = mp1.getPoint(i);
- Point p2 = mp2.getPoint(i);
- System.out.println("for rest: [" + p.getX() + "," + p.getY() + "]");
- System.out.println("for proj: [" + p2.getX() + "," + p2.getY()
- + "]");
- @SuppressWarnings("unused")
- double deltaX = p2.getX() - p.getX();
- @SuppressWarnings("unused")
- double deltaY = p2.getY() - p.getY();
-
- // Assert.assertTrue(deltaX<1e-7);
- // Assert.assertTrue(deltaY<1e-7);
- }
- }
-
- public enum SpatialRelationType {
- esriGeometryRelationCross, esriGeometryRelationDisjoint, esriGeometryRelationIn, esriGeometryRelationInteriorIntersection, esriGeometryRelationIntersection, esriGeometryRelationLineCoincidence, esriGeometryRelationLineTouch, esriGeometryRelationOverlap, esriGeometryRelationPointTouch, esriGeometryRelationTouch, esriGeometryRelationWithin, esriGeometryRelationRelation
- }
-
- public static boolean isRelationTrue(Geometry geometry1,
- Geometry geometry2, SpatialReference sr,
- SpatialRelationType relation, String relationParam) {
- String jsonStr4Geom1 = getJSonStringFromGeometry(geometry1, sr);
- String jsonStr4Geom2 = getJSonStringFromGeometry(geometry2, sr);
-
- Form f = new Form();
- f.add("sr", sr.getID());
- f.add("geometries1", jsonStr4Geom1);
- f.add("geometries2", jsonStr4Geom2);
-
- @SuppressWarnings("unused")
- String enumName = relation.name();
-
- f.add("relation", relation.name());
- f.add("f", "json");
- f.add("relationParam", relationParam);
-
- ClientResponse response = service4Relation.type(
- MediaType.APPLICATION_FORM_URLENCODED).post(
- ClientResponse.class, f);
- @SuppressWarnings("unused")
- boolean isOK = response.getClientResponseStatus() == ClientResponse.Status.OK;
- Object obj = response.getEntity(String.class);
- String jsonStr = obj.toString();
- int idx = jsonStr
- .lastIndexOf("geometry1Index\":0,\"geometry2Index\":0");
-
- if (idx == -1) {
- return false;
- } else {
- return true;
- }
- }
-
- static String getJSonStringFromGeometry(Geometry geomIn, SpatialReference sr) {
- String jsonStr4Geom = GeometryEngine.geometryToJson(sr, geomIn);
- String jsonStrNew = "{\"geometryType\":\"" + getGeometryType(geomIn)
- + "\",\"geometries\":[" + jsonStr4Geom + "]}";
- return jsonStrNew;
- }
-
- public static Geometry loadFromTextFileDbg(String textFileName)
- throws FileNotFoundException {
- String fullPath = textFileName;
- // string fullCSVPathName = System.IO.Path.Combine( directoryPath ,
- // CsvFileName);
- File fileInfo = new File(fullPath);
-
- Scanner scanner = new Scanner(fileInfo);
-
- Geometry geom = null;
-
- // grab first line
- String line = scanner.nextLine();
- String geomTypeString = line.substring(1);
- if (geomTypeString.equalsIgnoreCase("polygon"))
- geom = new Polygon();
- else if (geomTypeString.equalsIgnoreCase("polyline"))
- geom = new Polyline();
- else if (geomTypeString.equalsIgnoreCase("multipoint"))
- geom = new MultiPoint();
- else if (geomTypeString.equalsIgnoreCase("point"))
- geom = new Point();
-
- while (line.startsWith("*"))
- if (scanner.hasNextLine())
- line = scanner.nextLine();
-
- int j = 0;
- Geometry.Type geomType = geom.getType();
- while (scanner.hasNextLine()) {
- String[] parsedLine = line.split("\\s+");
- double xVal = Double.parseDouble(parsedLine[0]);
- double yVal = Double.parseDouble(parsedLine[1]);
- if (j == 0
- && (geomType == Geometry.Type.Polygon || geomType == Geometry.Type.Polyline))
- ((MultiPath) geom).startPath(xVal, yVal);
- else {
- if (geomType == Geometry.Type.Polygon
- || geomType == Geometry.Type.Polyline)
- ((MultiPath) geom).lineTo(xVal, yVal);
- else if (geomType == Geometry.Type.MultiPoint)
- ((MultiPoint) geom).add(xVal, yVal);
- // else if(geomType == Geometry.Type.Point)
- // Point geom = null;//new Point(xVal, yVal);
- }
- j++;
- line = scanner.nextLine();
- }
-
- scanner.close();
-
- return geom;
- }
-}
diff --git a/unittest/com/esri/core/geometry/TestConvexHull.java b/unittest/com/esri/core/geometry/TestConvexHull.java
deleted file mode 100644
index 72b6198a..00000000
--- a/unittest/com/esri/core/geometry/TestConvexHull.java
+++ /dev/null
@@ -1,963 +0,0 @@
-package com.esri.core.geometry;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestConvexHull extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public static void testDegenerate() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
- OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.DensifyByLength);
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(0, 0);
- polygon.lineTo(1, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(2, 0);
- polygon.lineTo(1, 0);
- polygon.lineTo(3, 0);
-
- polygon.startPath(0, 0);
- polygon.lineTo(1, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(2, 0);
- polygon.lineTo(1, 0);
- polygon.lineTo(3, 0);
-
- Polygon densified = (Polygon) (densify.execute(polygon, .5, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(convex_hull.calculateArea2D() == 0.0);
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 3.0 && p2.y == 0.0);
- }
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(NumberUtils.doubleEps(), 0);
- polygon.lineTo(0, NumberUtils.doubleEps());
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 5);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(0, 10);
- polygon.lineTo(0, 0);
-
- polygon.startPath(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 5);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(0, 10);
- polygon.lineTo(0, 0);
-
- polygon.startPath(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(5, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 5);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(0, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(0, 0);
-
- Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
-
- double area = convex_hull.calculateArea2D();
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(area == 100.0);
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 0.0 && p2.y == 10.0);
- assertTrue(p3.x == 10.0 && p3.y == 10.0);
- assertTrue(p4.x == 10.0 && p4.y == 0.0);
- }
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(0, 0);
- polygon.lineTo(0, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(5, 5);
- polygon.lineTo(5, 8);
- polygon.lineTo(10, 10);
- polygon.lineTo(10, 0);
-
- Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
-
- double area = convex_hull.calculateArea2D();
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(area == 100.0);
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 0.0 && p2.y == 10.0);
- assertTrue(p3.x == 10.0 && p3.y == 10.0);
- assertTrue(p4.x == 10.0 && p4.y == 0.0);
- }
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(5, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 5);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(10, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(0, 10);
- polygon.lineTo(5, 10);
- polygon.lineTo(0, 0);
- Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- double area = convex_hull.calculateArea2D();
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(area == 100.0);
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 0.0 && p2.y == 10.0);
- assertTrue(p3.x == 10.0 && p3.y == 10.0);
- assertTrue(p4.x == 10.0 && p4.y == 0.0);
- }
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(0, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(0, 10);
- polygon.lineTo(0, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(0, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(0, 0);
-
- polygon.startPath(0, 10);
- polygon.lineTo(0, 10);
- polygon.lineTo(10, 10);
- polygon.lineTo(0, 10);
- polygon.lineTo(10, 0);
- polygon.lineTo(0, 10);
- polygon.lineTo(0, 0);
- polygon.lineTo(0, 10);
-
- polygon.startPath(10, 10);
- polygon.lineTo(10, 10);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(0, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(0, 10);
- polygon.lineTo(10, 10);
-
- polygon.startPath(10, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(10, 0);
- polygon.lineTo(0, 10);
- polygon.lineTo(10, 0);
- polygon.lineTo(10, 10);
- polygon.lineTo(10, 0);
-
- Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- assertTrue(bounding.isConvex(convex_hull, null));
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 0.0 && p2.y == 10.0);
- assertTrue(p3.x == 10.0 && p3.y == 10.0);
- assertTrue(p4.x == 10.0 && p4.y == 0.0);
- }
-
- {
- MultiPoint mpoint = new MultiPoint();
- mpoint.add(4, 4);
- mpoint.add(4, 4);
- mpoint.add(4, 4);
- mpoint.add(4, 4);
-
- Polygon convex_hull = (Polygon) (bounding.execute(mpoint, null));
- assertTrue(convex_hull.getPointCount() == 2);
- assertTrue(convex_hull.calculateArea2D() == 0.0);
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- MultiPoint mpoint = new MultiPoint();
- mpoint.add(4, 4);
-
- MultiPoint convex_hull = (MultiPoint) (bounding.execute(mpoint,
- null));
- assertTrue(convex_hull.getPointCount() == 1);
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(convex_hull == mpoint);
- }
-
- {
- MultiPoint mpoint = new MultiPoint();
- mpoint.add(4, 4);
- mpoint.add(4, 5);
-
- Polyline convex_hull = (Polyline) (bounding.execute(mpoint, null));
- assertTrue(convex_hull.getPointCount() == 2);
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(convex_hull.calculateLength2D() == 1.0);
- }
-
- {
- Line line = new Line();
- line.setStartXY(0, 0);
- line.setEndXY(0, 1);
-
- Polyline convex_hull = (Polyline) (bounding.execute(line, null));
- assertTrue(convex_hull.getPointCount() == 2);
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(convex_hull.calculateLength2D() == 1.0);
- }
-
- {
- Polyline polyline = new Polyline();
- polyline.startPath(0, 0);
- polyline.lineTo(0, 1);
-
- Polyline convex_hull = (Polyline) (bounding.execute(polyline, null));
- assertTrue(convex_hull.getPointCount() == 2);
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(polyline == convex_hull);
- assertTrue(convex_hull.calculateLength2D() == 1.0);
- }
-
- {
- Envelope env = new Envelope(0, 0, 10, 10);
-
- Envelope convex_hull = (Envelope) (bounding.execute(env, null));
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(env == convex_hull);
- }
- }
-
- @Test
- public static void testSquare() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
- OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.DensifyByLength);
- OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Difference);
- OperatorContains contains = (OperatorContains) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Contains);
-
- Polygon square = new Polygon();
- square.startPath(0, 0);
- square.lineTo(2, 3);
- square.lineTo(1, 4);
- square.lineTo(0, 5);
- square.lineTo(0, 7);
- square.lineTo(2, 7);
- square.lineTo(0, 10);
- square.lineTo(4, 7);
- square.lineTo(6, 7);
- square.lineTo(7, 10);
- square.lineTo(8, 10);
- square.lineTo(10, 10);
- square.lineTo(8, 7);
- square.lineTo(10, 5);
- square.lineTo(8, 3);
- square.lineTo(10, 1);
- square.lineTo(10, 0);
- square.lineTo(5, 5);
- square.lineTo(8, 0);
- square.lineTo(4, 3);
- square.lineTo(5, 0);
- square.lineTo(3, 1);
- square.lineTo(3, 0);
- square.lineTo(2, 1);
-
- Polygon densified = (Polygon) (densify.execute(square, 1.0, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- Polygon differenced = (Polygon) (difference.execute(densified,
- convex_hull, SpatialReference.create(4326), null));
-
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- @Test
- public static void testPolygons() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
- OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.DensifyByLength);
- OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Difference);
-
- {
- Polygon shape = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[1.3734426370715553,-90],[-24.377532184629967,-63.428606327053856],[-25.684686546621553,90],[-24.260574484321914,80.526315789473699],[-25.414389575040037,90],[-23.851448513708718,90],[-23.100135788742072,87.435887853000679],[5.6085096351011448,-48.713222410606306],[1.3734426370715553,-90]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(shape, null));
- Polygon differenced = (Polygon) (difference.execute(shape,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-179.64843749999693,-43.3535476539993],[-179.99999999999696,-43.430006211999284],[-179.99999999999696,39.329644416999436],[-179.64843749999693,38.98862638799943],[-89.99999999999838,29.008084980999506],[-112.8515624999981,-16.20113770599962],[-115.66406249999804,-18.882554574999688],[-124.80468749999788,-23.7925511709996],[-138.86718749999767,-30.6635901109995],[-157.49999999999736,-38.468358112999354],[-162.42187499999724,-39.56498442199932],[-179.64843749999693,-43.3535476539993]],[[179.99999999999696,-43.430006211999284],[179.64843749999693,-43.50646476999926],[162.0703124999973,-42.36267115399919],[160.3124999999973,-42.24790485699929],[143.78906249999756,-41.1680427339993],[138.16406249999767,-39.64744846799925],[98.43749999999845,-28.523889212999524],[78.39843749999878,-5.1644422999998705],[75.9374999999988,19.738611663999766],[88.2421874999986,33.51651305599954],[108.63281249999815,44.160795160999356],[138.16406249999767,51.02062617799914],[140.9765624999976,51.68129673399923],[160.3124999999973,52.8064856429991],[162.0703124999973,52.908902047999206],[163.12499999999727,52.97036560499911],[165.93749999999716,52.97036560499911],[179.99999999999696,39.329644416999436],[179.99999999999696,-43.430006211999284]]]}")
- .getGeometry());
- Polygon densified = (Polygon) (densify.execute(polygon, 10.0, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- Polygon differenced = (Polygon) (difference.execute(densified,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(1, 0);
- polygon.lineTo(-1, 0);
- polygon.lineTo(0, -1);
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-38.554566833914528,21.902000764339238],[-30.516168471666138,90],[-38.554566833914528,21.902000764339238]],[[-43.013227444613932,28.423410187206883],[-43.632473335895916,90],[-42.342268693420237,62.208637129146894],[-37.218731802058755,63.685357222187029],[-32.522681335230686,47.080307818055296],[-40.537308829621097,-21.881392019745604],[-47.59510451722663,18.812521648505964],[-53.25344489340366,30.362745244224911],[-46.629060462410138,90],[-50.069277433245119,18.254168921734287],[-42.171214434397982,72.623347387008081],[-43.000844452530551,90],[-46.162281544954659,90],[-39.462049205071331,90],[-47.434856316742902,38.662565208814371],[-52.13115779642537,-19.952586632199857],[-56.025328966335081,90],[-60.056846215416158,-44.023645282268355],[-60.12338894192289,50.374596189881942],[-35.787508034048379,-7.8839007676038513],[-60.880218074135605,-46.447995750907815],[-67.782542852117956,-85.106300958016107],[-65.053131764313761,-0.96651520578494665],[-72.375821140304154,90],[-78.561502106749245,90],[-83.809168672565946,33.234498214085811],[-60.880218054506344,-46.447995733653201],[-75.637095425108981,59.886574792622838],[-71.364085965028096,31.976373491332097],[-67.89968380886117,90],[-67.544349171474749,8.8435794458927504],[-70.780047377934707,80.683454463576624],[-64.996733940204948,34.349882797035313],[-56.631753638680905,39.815838152456926],[-60.392350183516896,52.75446132093407],[-58.51633728692137,90],[-64.646972065627097,41.444197803942579],[-73.355591244695518,-0.15370205145035776],[-43.013227444613932,28.423410187206883]],[[-69.646471076946,-85.716191379686904],[-62.854465128320491,-45.739046580967972],[-71.377481570643141,-90],[-66.613495837251435,-90],[-66.9765142407159,-90],[-66.870099169607329,-90],[-67.23180828626819,-61.248439074609649],[-58.889775875438851,-90],[-53.391995883729322,-69.476385967096491],[-69.646471076946,-85.716191379686904]]]}")
- .getGeometry());
- Polygon densified = (Polygon) (densify.execute(polygon, 10.0, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- Polygon differenced = (Polygon) (difference.execute(densified,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- // assertTrue(bounding.isConvex(*convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-38.554566833914528,21.902000764339238],[-30.516168471666138,90],[-38.554566833914528,21.902000764339238]],[[-43.013227444613932,28.423410187206883],[-43.632473335895916,90],[-42.342268693420237,62.208637129146894],[-37.218731802058755,63.685357222187029],[-32.522681335230686,47.080307818055296],[-40.537308829621097,-21.881392019745604],[-47.59510451722663,18.812521648505964],[-53.25344489340366,30.362745244224911],[-46.629060462410138,90],[-50.069277433245119,18.254168921734287],[-42.171214434397982,72.623347387008081],[-43.000844452530551,90],[-46.162281544954659,90],[-39.462049205071331,90],[-47.434856316742902,38.662565208814371],[-52.13115779642537,-19.952586632199857],[-56.025328966335081,90],[-60.056846215416158,-44.023645282268355],[-60.12338894192289,50.374596189881942],[-35.787508034048379,-7.8839007676038513],[-60.880218074135605,-46.447995750907815],[-67.782542852117956,-85.106300958016107],[-65.053131764313761,-0.96651520578494665],[-72.375821140304154,90],[-78.561502106749245,90],[-83.809168672565946,33.234498214085811],[-60.880218054506344,-46.447995733653201],[-75.637095425108981,59.886574792622838],[-71.364085965028096,31.976373491332097],[-67.89968380886117,90],[-67.544349171474749,8.8435794458927504],[-70.780047377934707,80.683454463576624],[-64.996733940204948,34.349882797035313],[-56.631753638680905,39.815838152456926],[-60.392350183516896,52.75446132093407],[-58.51633728692137,90],[-64.646972065627097,41.444197803942579],[-73.355591244695518,-0.15370205145035776],[-43.013227444613932,28.423410187206883]],[[-69.646471076946,-85.716191379686904],[-62.854465128320491,-45.739046580967972],[-71.377481570643141,-90],[-66.613495837251435,-90],[-66.9765142407159,-90],[-66.870099169607329,-90],[-67.23180828626819,-61.248439074609649],[-58.889775875438851,-90],[-53.391995883729322,-69.476385967096491],[-69.646471076946,-85.716191379686904]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-36.269498017702901,-26.37490682626369],[-49.146436641060951,-49.881862499696126],[-37.560006446488146,-45.592052597656789],[-39.13770692863632,-69.085816352131204],[-65.415587331361877,-90],[-51.462290812033373,-16.760787566546721],[-28.454456182408332,90],[-36.269498017702901,-26.37490682626369]],[[-40.542178258552283,-90],[-39.13770692863632,-69.085816352131204],[-16.295804332590937,-50.906277575066262],[-40.542178258552283,-90]],[[-16.295804332590937,-50.906277575066262],[-5.6790432913971927,-33.788307256548933],[14.686101893282586,-26.248228042967728],[-16.295804332590937,-50.906277575066262]],[[-37.560006446488146,-45.592052597656789],[-36.269498017702901,-26.37490682626369],[27.479825940672225,90],[71.095881152477034,90],[-5.6790432913971927,-33.788307256548933],[-37.560006446488146,-45.592052597656789]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-77.020281185856106,-80.085419699581706],[-77.328568930885723,-83.404479889897416],[-80.495259564600545,-90],[-77.020281185856106,-80.085419699581706]],[[-77.941187535385211,-90],[-77.328568930885723,-83.404479889897416],[-39.252034383972621,-4.0994329574862469],[-39.29471328421063,-6.5269494453154593],[-77.941187535385211,-90]],[[-77.020281185856106,-80.085419699581706],[-62.688864277996522,74.208210509833052],[-38.108861278327581,80.371071656873013],[-37.597643844595929,90],[-38.663943358642484,29.350366647752089],[-77.020281185856106,-80.085419699581706]],[[-40.265125886194951,-61.722668598742551],[-39.29471328421063,-6.5269494453154593],[-15.554402498931253,44.750073899273843],[-8.4447006412989474,13.127318978368956],[-5.310206313296316,-4.5170390491918795],[-40.265125886194951,-61.722668598742551]],[[-39.252034383972621,-4.0994329574862469],[-38.663943358642484,29.350366647752089],[-22.476078360563164,75.536520897660651],[-15.632105532320049,45.095683888365997],[-39.252034383972621,-4.0994329574862469]],[[-15.554402498931253,44.750073899273843],[-15.632105532320049,45.095683888365997],[-8.9755856576261941,58.959750756602595],[-15.554402498931253,44.750073899273843]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-68.840007952128175,37.060080998089632],[-68.145986924561413,31.114096694815196],[-69.187773850176768,30.693518246958952],[-68.840007952128175,37.060080998089632]],[[-75.780513355389928,-90],[-69.21567111077384,30.182802098042274],[-50.875629803516389,37.146119571446704],[-75.780513355389928,-90]],[[4.2911006174797457,-1.144569312564311],[-66.484019915251849,80.191238371060038],[-65.948228008382316,90],[4.2911006174797457,-1.144569312564311]],[[-90,22.291441435181515],[-69.187773850176768,30.693518246958952],[-69.21567111077384,30.182802098042274],[-90,22.291441435181515]],[[-68.840007952128175,37.060080998089632],[-75.019206401201359,90],[-66.484019915251849,80.191238371060038],[-68.840007952128175,37.060080998089632]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[27.570109889215438,22.850616190228489],[75.703105729477357,-90],[2.1548000876241362,-15.817792950796967],[27.570109889215438,22.850616190228489]],[[-0.069915984436478951,-90],[-46.602410662754053,-89.999999998014729],[-14.977190481820156,-41.883452819243004],[-0.069915984436478951,-90]],[[-14.977190481820156,-41.883452819243004],[-34.509989609682322,21.163004866431177],[2.1548000876241362,-15.817792950796967],[-14.977190481820156,-41.883452819243004]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[28.865673900286581,33.379551302126075],[39.505669183485338,-34.957993133630559],[7.152466542048213,-90],[28.865673900286581,33.379551302126075]],[[-64.597291313620858,2.4515644574812248],[20.050002923927103,90],[24.375150856531356,62.220853377417541],[-64.597291313620858,2.4515644574812248]],[[28.865673900286581,33.379551302126075],[24.375150856531356,62.220853377417541],[35.223952527956932,69.508785974507163],[28.865673900286581,33.379551302126075]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-66.582505384413167,-51.305212522944061],[-60.169897093348865,-90],[-90,-90],[-66.582505384413167,-51.305212522944061]],[[20.858462934004656,-90],[-35.056287147954386,0.78833269359179781],[18.933251883215579,90],[20.858462934004656,-90]],[[-66.582505384413167,-51.305212522944061],[-90,90],[-35.056287147954386,0.78833269359179781],[-66.582505384413167,-51.305212522944061]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[36.692916710279974,-90],[-31.182443792600079,6.434474852744998],[-90,90],[52.245260790065387,57.329280208760991],[36.692916710279974,-90]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-17.959089916602533,-4.3577640799248218],[-29.181784251472308,-90],[-65.493717350127127,15.053615507086979],[-17.959089916602533,-4.3577640799248218]],[[-21.884657435973146,-34.517617672142393],[-17.94005076020704,-4.3655389655558539],[9.3768748358343359,-15.520758655380195],[-21.884657435973146,-34.517617672142393]],[[-17.94005076020704,-4.3655389655558539],[-17.959089916602533,-4.3577640799248218],[-5.8963967801936494,87.694641571893939],[-17.94005076020704,-4.3655389655558539]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[17.198360589495572,-77.168667157542373],[-24.835678541343281,-83.717338556412017],[-30.259244993378722,61.914816728303791],[17.198360589495572,-77.168667157542373]],[[-8.3544985146710644,-90],[17.979891823366039,-79.459092168186686],[21.576625471325329,-90],[-8.3544985146710644,-90]],[[17.979891823366039,-79.459092168186686],[17.198360589495572,-77.168667157542373],[27.846596597209441,-75.509730732825361],[17.979891823366039,-79.459092168186686]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-1.2588613620456419,13.607321860624268],[61.845346679259052,48.415944386573557],[15.226225965240992,-5.3702891526017318],[0.92681706095183469,1.6819284384951441],[3.8469417404317623,-14.250715301799051],[7.2615297628459139,-14.559458820527061],[4.4896578086498238,-17.757471781424698],[14.589138845678622,-72.861774161244625],[-10.508572009494033,-35.06149380752737],[-58.12642296329372,-90],[-15.260062192400673,90],[-1.2588613620456419,13.607321860624268]],[[0.92681706095183469,1.6819284384951441],[-1.2588613620456419,13.607321860624268],[-11.641308877525201,7.8803076458946304],[0.92681706095183469,1.6819284384951441]],[[-10.508572009494033,-35.06149380752737],[4.4896578086498238,-17.757471781424698],[3.8469417404317623,-14.250715301799051],[-26.125369947914503,-11.54064986657559],[-10.508572009494033,-35.06149380752737]],[[39.829571435268129,-17.504227477249202],[7.2615297628459139,-14.559458820527061],[15.226225965240992,-5.3702891526017318],[39.829571435268129,-17.504227477249202]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-19.681975166855118,-34.10344217707847],[-90,89.999999998418275],[53.036316534501381,90],[-19.681975166855118,-34.10344217707847]],[[-52.434509065706855,-90],[-29.2339442498794,-50.405148598356135],[-2.8515119199232331,-90],[-52.434509065706855,-90]],[[18.310881874573923,-90],[-25.473718245381271,-43.987822508814972],[-19.681975166855118,-34.10344217707847],[-15.406194071963924,-41.649717163101563],[18.310881874573923,-90]],[[-29.2339442498794,-50.405148598356135],[-52.27954259799813,-15.81822990020261],[-25.473718245381271,-43.987822508814972],[-29.2339442498794,-50.405148598356135]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[49.939516827702498,-90],[-20.470128740962011,-68.102019032647391],[-20.124197553433845,-67.213968219799824],[34.438329237618149,-61.893901496061034],[49.939516827702498,-90]],[[-82.380918375714089,-73.284249936115529],[-4.7432060543229699,9.1484031048644194],[-11.790524932251525,21.926303986370414],[-3.4862200343039369,10.483021157965428],[19.753975453441285,35.158541777575607],[5.5896897290794696,-1.2030408273476854],[73.839023528563189,-58.052174675157325],[34.438329237618149,-61.893901496061034],[3.6757233436274213,-6.1164440290327313],[-20.124197553433845,-67.213968219799824],[-82.380918375714089,-73.284249936115529]],[[5.5896897290794696,-1.2030408273476854],[4.0842948437219349,0.050896618883412792],[-3.4862200343039369,10.483021157965428],[-4.7432060543229699,9.1484031048644194],[3.6757233436274213,-6.1164440290327313],[5.5896897290794696,-1.2030408273476854]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[4.7618727814345867,-14.245890151885444],[-7.1675180359486266,-90],[-83.232840716292529,40.620187389409224],[-29.219286930421923,6.9418934044755334],[-29.378277853968513,6.9629531745072839],[-28.933835455648254,6.7639099538036529],[4.7618727814345867,-14.245890151885444]],[[51.056303527367277,-43.111190419066219],[4.7618727814345867,-14.245890151885444],[5.632592229367642,-8.716640778187827],[-28.933835455648254,6.7639099538036529],[-29.219286930421923,6.9418934044755334],[2.700964609629902,2.7137705544807242],[12.385960896403816,0.48342578457646468],[51.056303527367277,-43.111190419066219]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-21.426619830983732,-89.379667629404466],[-72.784461583687971,-88.999754827814016],[-81.94289434769162,25.456737039611831],[-38.382426191605546,-57.204127144336077],[-41.663734179022256,-78.439084394036513],[-29.749353943865881,-73.586348060869426],[-21.426619830983732,-89.379667629404466]],[[-21.09971823441461,-90],[-21.426619830983732,-89.379667629404466],[-21.080965849893449,-89.382224558742934],[-21.09971823441461,-90]],[[62.431917153693021,-90],[-21.080965849893449,-89.382224558742934],[-20.486971473666468,-69.813772479288062],[19.166418765782844,-53.662915804391695],[63.671046682728601,-90],[62.431917153693021,-90]],[[-29.749353943865881,-73.586348060869426],[-38.382426191605546,-57.204127144336077],[-31.449272112025476,-12.336278393150847],[-41.028899505665962,-4.5147159296945967],[-30.750049689226596,-7.8112663207986941],[-15.63587330244308,90],[-18.721998818789388,-11.66880646480822],[60.158611185675326,-36.966763960486929],[19.166418765782844,-53.662915804391695],[-19.049573405176112,-22.46036923493498],[-20.486971473666468,-69.813772479288062],[-29.749353943865881,-73.586348060869426]],[[-19.049573405176112,-22.46036923493498],[-18.721998818789388,-11.66880646480822],[-30.750049689226596,-7.8112663207986941],[-31.449272112025476,-12.336278393150847],[-19.049573405176112,-22.46036923493498]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-17.906614911617162,-53.670186894017093],[-72.687715727164573,-90],[-77.889582483879749,90],[-47.149885004784061,16.372797801863811],[-58.874489264131405,8.3403055152440846],[-44.017112148517498,8.8692333739436133],[-43.760297522359615,8.2541153357643502],[-48.398890069305921,4.7201397602360009],[-38.665987052649818,-3.9476907252248874],[-17.906614911617162,-53.670186894017093]],[[-2.7387498969355368,-90],[-17.906614911617162,-53.670186894017093],[-6.8038688963847829,-46.30705103709559],[-2.7387498969355368,-90]],[[-6.8038688963847829,-46.30705103709559],[-8.2224486207861638,-31.0597897622158],[2.1962303277340673,-40.338351652092697],[-6.8038688963847829,-46.30705103709559]],[[-8.2224486207861638,-31.0597897622158],[-38.665987052649818,-3.9476907252248874],[-43.760297522359615,8.2541153357643502],[-42.90074612601282,8.9089763975751382],[-44.017112148517498,8.8692333739436133],[-47.149885004784061,16.372797801863811],[45.190674429223662,79.635046572817728],[40.490070954305672,72.441418146356597],[63.53694979672099,90],[75.056911135062407,13.108310545642606],[-0.027204347469059975,10.435289586728711],[-10.580480746811602,-5.715051428780245],[-8.2224486207861638,-31.0597897622158]],[[-42.90074612601282,8.9089763975751382],[-0.027204347469059975,10.435289586728711],[40.490070954305672,72.441418146356597],[-42.90074612601282,8.9089763975751382]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
- Polygon differenced = (Polygon) (difference.execute(polygon,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
- }
-
- @Test
- public static void testPolylines() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
- OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.DensifyByLength);
- OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Difference);
- OperatorContains contains = (OperatorContains) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Contains);
-
- {
- Polyline poly = new Polyline();
- poly.startPath(0, 0);
- poly.lineTo(0, 10);
- poly.lineTo(0, 20);
- poly.lineTo(0, 40);
- poly.lineTo(0, 500);
-
- Polyline densified = (Polyline) (densify.execute(poly, 10.0, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- Polyline differenced = (Polyline) (difference.execute(densified,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polyline polyline = new Polyline();
- polyline.startPath(-200, -90);
- polyline.lineTo(-180, -85);
- polyline.lineTo(-90, -70);
- polyline.lineTo(0, 0);
- polyline.lineTo(100, 25);
- polyline.lineTo(170, 45);
- polyline.lineTo(225, 65);
-
- Polyline densified = (Polyline) (densify.execute(polyline, 10.0,
- null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- boolean bcontains = contains.execute(convex_hull, densified,
- SpatialReference.create(4326), null);
-
- assertTrue(bcontains);
- assertTrue(bounding.isConvex(convex_hull, null));
- }
- }
-
- @Test
- public static void testNonSimpleShape() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
- OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.DensifyByLength);
- OperatorDifference difference = (OperatorDifference) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Difference);
- OperatorContains contains = (OperatorContains) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Contains);
-
- {
- Polygon shape = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[6.7260599916745036,-90],[15.304037095218971,-18.924146439950675],[6.3163297788539232,-90],[5.2105387036445823,-59.980719950158637],[5.1217504663506981,-60.571174400735508],[8.2945138368731044,-27.967042187979146],[15.76606600357545,28.594953216378414],[8.4365340991447919,66.880924521951329],[10.115022726199774,65.247385313781265],[12.721206966604395,-23.793016208456883],[12.051875868947576,-11.368909618476637],[11.867118776841318,44.968896646914239],[7.5326099218274614,35.095776924526533],[8.86765609460479,90],[3.2036592678446922,55.507964789691712],[0.23585282258761486,-42.620591380394039],[-1.2660432762142744,90],[5.5580612840503001,-9.4879902323389196],[12.258387597532487,-35.945231749575591],[-48.746716054894101,90],[7.2294405148356846,-15.719232058488402],[13.798313011339591,-10.467172541381753],[7.4430022048746718,6.3951685161785656],[6.4876332898327815,31.10016146737189],[9.3645424359058911,47.123308099298804],[13.398605254542668,-6.4398318586014325],[-90,90],[13.360786277212718,82.971274676174545],[7.9405631778693566,90],[10.512482079680538,90],[16.994982794293946,19.60673041736408],[16.723893839323615,22.728853852102926],[23.178783416627525,90],[6.7260599916745036,-90]],[[26.768777234301993,90],[20.949797955126346,90],[11.967758262201434,-0.45048849056049711],[17.535751576687339,52.767528591651441],[26.768777234301993,90]],[[18.677765775891793,12.559680067559942],[19.060218406331451,90],[17.123595624401705,90],[-2.3805299720687887,-90],[-11.882782057881979,-90],[21.640575461689693,90],[11.368255808198477,85.501555553904794],[17.390084032215348,90],[23.999392897519989,78.255909006554603],[-6.8860811786563101,69.49189433189926],[29.232578855788898,90],[25.951412073846683,90],[-5.5572284181160772,-16.763772082849457],[18.677765775891793,12.559680067559942]]]}")
- .getGeometry());
- Polygon densified = (Polygon) (densify.execute(shape, 10.0, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- Polygon differenced = (Polygon) (difference.execute(densified,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon shape = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-13.630596027421603,3.6796011190640709],[-10.617275202716886,-28.133054337834409],[-81.617315194491695,90],[-4.0763362539824293,-90],[2.8213537979804073,-90],[-5.1515857979973365,-11.605767592612787],[43.477754021411123,35.507543731267589],[-45.818261267516704,-90],[-4.8545715514870018,-64.204371906322223],[-1.744951154293144,-30.257848194381509],[-7.8524748309267149,15.513561279453089],[-10.657563385538953,-81.785061432086309],[-6.3487369893289411,-31.849779201388415],[-14.768278524737962,-12.004393281111058],[-27.001635582579841,90],[-14.967554248940855,-78.970629918591811],[-12.999635147475825,-38.584472796107939],[-13.630596027421603,3.6796011190640709]],[[-16.338143621861352,-37.415690513288375],[-21.553879270366266,-90],[-18.649338100909404,-90],[-24.880584966233631,1.3133858590648728],[-16.483464632078249,-53.979692212288882],[-24.836979215403964,-68.69859399640147],[-29.708282990385214,-90],[-27.469962102507036,-1.6392995673644872],[-20.405051753708271,61.943199597870034],[-18.242567838912599,24.405109362934219],[-66.334547696572528,-52.678390155566603],[-13.471083255903507,-33.782708412943229],[-7.092757068096085,33.673785662500464],[-2.7427100969018205,74.386868339212668],[-8.2174861339989675,90],[-15.699459164009667,90],[-9.5910045204059156,90],[-8.4504603287557369,90],[-1.5498862802092637,2.5144190340747681],[-6.5326327868410639,-17.428029961128306],[-10.947786354404593,31.516236387466538],[-7.4777936485986354,12.486727826508769],[-13.89052186883092,12.397126427870356],[-10.530672679779606,-55.463541447339118],[-8.7161833631330374,-90],[-4.7231067612639519,-90],[-3.9692500849117041,-32.204677519048822],[3.740804266163555,32.88191805391007],[6.2021313886056246,76.617541950091564],[6.1183997672398194,90],[0.59730820015390673,90],[7.3242950674530753,18.030401540676614],[1.8252371571535342,90],[-16.338143621861352,-37.415690513288375]]]}")
- .getGeometry());
- Polygon densified = (Polygon) (densify.execute(shape, 10.0, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
- Polygon differenced = (Polygon) (difference.execute(densified,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon shape = (Polygon) (TestCommonMethods
- .fromJson("{\"rings\":[[[-11.752662474672046,-90],[-76.236530072126513,7.3247326417920817],[18.933251883215579,90],[51.538924439116798,90],[52.253017336758049,80.352482145105284],[41.767201918260639,51.890297432229289],[21.697252770910882,-1.3185641048567049],[45.112193442818935,60.758441021743636],[48.457184967377231,69.626584611257954],[49.531808284502759,70.202152706968036],[52.394797054144334,71.533541126234581],[ 52.9671102343993,70.704964290210626],[58.527850348069251,16.670036266565845],[62.310807912773328,-34.249918700039238],[62.775020703241523,-43.541598916699364],[64.631871865114277,-80.708319783339874],[65.096084655582459,-90],[-11.752662474672046,-90]]]}")
- .getGeometry());
- Polygon convex_hull = (Polygon) (bounding.execute(shape, null));
- Polygon differenced = (Polygon) (difference.execute(shape,
- convex_hull, SpatialReference.create(4326), null));
- assertTrue(differenced.isEmpty());
- assertTrue(bounding.isConvex(convex_hull, null));
- }
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(0, 0);
- polygon.lineTo(0, 10);
- polygon.lineTo(4, 10);
- polygon.lineTo(9, 1);
- polygon.lineTo(1, 1);
- polygon.lineTo(5, 10);
- polygon.lineTo(10, 10);
- polygon.lineTo(10, 0);
-
- Polygon densified = (Polygon) (densify.execute(polygon, 1, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
-
- double area = convex_hull.calculateArea2D();
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(area == 100.0);
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 0.0 && p2.y == 10.0);
- assertTrue(p3.x == 10.0 && p3.y == 10.0);
- assertTrue(p4.x == 10.0 && p4.y == 0.0);
- }
-
- {
- Polygon polygon = new Polygon();
- polygon.startPath(0, 0);
- polygon.lineTo(0, 10);
- polygon.lineTo(8, 10);
- polygon.lineTo(10, 8);
- polygon.lineTo(10, 0);
- polygon.lineTo(0, 0);
- polygon.lineTo(0, 10);
- polygon.lineTo(10, 10);
- polygon.lineTo(10, 0);
-
- // Polygon densified = (Polygon)(densify.execute(polygon, 1, null));
- Polygon convex_hull = (Polygon) (bounding.execute(polygon, null));
-
- double area = convex_hull.calculateArea2D();
- assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(area == 100.0);
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 0.0 && p2.y == 10.0);
- assertTrue(p3.x == 10.0 && p3.y == 10.0);
- assertTrue(p4.x == 10.0 && p4.y == 0.0);
- }
- }
-
- @Test
- public static void testStar() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
- OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.DensifyByLength);
-
- Polygon star = new Polygon();
- star.startPath(0, 0);
- star.lineTo(0, 0);
- star.lineTo(5, 10);
- star.lineTo(5, 10);
- star.lineTo(10, 0);
- star.lineTo(10, 0);
- star.startPath(0, 5);
- star.lineTo(0, 5);
- star.lineTo(10, 5);
- star.lineTo(10, 5);
- star.lineTo(5, -5);
- star.lineTo(5, -5);
-
- star.reversePath(1);
-
- Polygon densified = (Polygon) (densify.execute(star, 1.0, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
-
- assertTrue(bounding.isConvex(convex_hull, null));
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- Point2D p5 = convex_hull.getXY(4);
- Point2D p6 = convex_hull.getXY(5);
- assertTrue(p1.x == 0.0 && p1.y == 0.0);
- assertTrue(p2.x == 0.0 && p2.y == 5.0);
- assertTrue(p3.x == 5.0 && p3.y == 10.0);
- assertTrue(p4.x == 10.0 && p4.y == 5.0);
- assertTrue(p5.x == 10.0 && p5.y == 0.0);
- assertTrue(p6.x == 5.0 && p6.y == -5.0);
- }
-
- @Test
- public static void testPointsArray() {
- Point2D[] points = new Point2D[6];
- int[] convex_hull = new int[6];
-
- for (int i = 0; i < 6; i++)
- points[i] = new Point2D();
-
- points[0].x = 0;
- points[0].y = 0;
- points[1].x = 5;
- points[1].y = 10;
- points[2].x = 10;
- points[2].y = 0;
- points[3].x = 0;
- points[3].y = 5;
- points[4].x = 10;
- points[4].y = 5;
- points[5].x = 5;
- points[5].y = -5;
-
- ConvexHull.construct(points, 6, convex_hull);
- assertTrue(convex_hull[0] == 0);
- assertTrue(convex_hull[1] == 3);
- assertTrue(convex_hull[2] == 1);
- assertTrue(convex_hull[3] == 4);
- assertTrue(convex_hull[4] == 2);
- assertTrue(convex_hull[5] == 5);
- }
-
- @Test
- public static void testMergeCursor() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
-
- Polygon geom1 = new Polygon();
- Polygon geom2 = new Polygon();
- Point geom3 = new Point();
- Line geom4 = new Line();
- Envelope geom5 = new Envelope();
- MultiPoint geom6 = new MultiPoint();
-
- // polygon
- geom1.startPath(0, 0);
- geom1.lineTo(0, 0);
- geom1.lineTo(5, 11);
- geom1.lineTo(5, 11);
- geom1.lineTo(10, 0);
- geom1.lineTo(10, 0);
-
- // polygon
- geom2.startPath(0, 5);
- geom2.lineTo(0, 5);
- geom2.lineTo(10, 5);
- geom2.lineTo(10, 5);
- geom2.lineTo(5, -5);
- geom2.lineTo(5, -5);
-
- // point
- geom3.setXY(15, 1.25);
-
- // segment
- geom4.setEndXY(-5, 1.25);
- geom4.setStartXY(0, 0);
-
- // envelope
- geom5.setCoords(0, 0, 5, 10);
-
- // multi_point
- geom6.add(10, 5);
- geom6.add(10, 10);
-
- // create cursor
- Geometry[] geoms = new Geometry[6];
- geoms[0] = geom1;
- geoms[1] = geom2;
- geoms[2] = geom3;
- geoms[3] = geom4;
- geoms[4] = geom5;
- geoms[5] = geom6;
- GeometryCursor cursor = new SimpleGeometryCursor(geoms);
-
- // create convex hull from the cursor with b_merge set to true
- GeometryCursor convex_hull_curs = bounding.execute(cursor, true, null);
- Polygon convex_hull = (Polygon) (convex_hull_curs.next());
- assertTrue(convex_hull_curs.next() == null);
-
- assertTrue(bounding.isConvex(convex_hull, null));
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- Point2D p5 = convex_hull.getXY(4);
- Point2D p6 = convex_hull.getXY(5);
- assertTrue(p1.x == 5.0 && p1.y == 11.0);
- assertTrue(p2.x == 10.0 && p2.y == 10);
- assertTrue(p3.x == 15.0 && p3.y == 1.25);
- assertTrue(p4.x == 5.0 && p4.y == -5.0);
- assertTrue(p5.x == -5.0 && p5.y == 1.25);
- assertTrue(p6.x == 0.0 && p6.y == 10.0);
-
- // Test GeometryEngine
- Geometry[] merged_hull = GeometryEngine.convexHull(geoms, true);
- convex_hull = (Polygon) merged_hull[0];
- p1 = convex_hull.getXY(0);
- p2 = convex_hull.getXY(1);
- p3 = convex_hull.getXY(2);
- p4 = convex_hull.getXY(3);
- p5 = convex_hull.getXY(4);
- p6 = convex_hull.getXY(5);
- assertTrue(p1.x == 5.0 && p1.y == 11.0);
- assertTrue(p2.x == 10.0 && p2.y == 10);
- assertTrue(p3.x == 15.0 && p3.y == 1.25);
- assertTrue(p4.x == 5.0 && p4.y == -5.0);
- assertTrue(p5.x == -5.0 && p5.y == 1.25);
- assertTrue(p6.x == 0.0 && p6.y == 10.0);
-
- }
-
- @Test
- public void testHullTickTock() {
- Polygon geom1 = new Polygon();
- Polygon geom2 = new Polygon();
- Point geom3 = new Point();
- Line geom4= new Line();
- Envelope geom5 = new Envelope();
- MultiPoint geom6 = new MultiPoint();
-
- // polygon
- geom1.startPath(0, 0);
- geom1.lineTo(0, 0);
- geom1.lineTo(5, 11);
- geom1.lineTo(5, 11);
- geom1.lineTo(10, 0);
- geom1.lineTo(10, 0);
-
- // polygon
- geom2.startPath(0, 5);
- geom2.lineTo(0, 5);
- geom2.lineTo(10, 5);
- geom2.lineTo(10, 5);
- geom2.lineTo(5, -5);
- geom2.lineTo(5, -5);
-
- // point
- geom3.setXY(15, 1.25);
-
- // segment
- geom4.setEndXY(-5, 1.25);
- geom4.setStartXY(0, 0);
-
- // envelope
- geom5.setCoords(0, 0, 5, 10);
-
- // multi_point
- geom6.add(10, 5);
- geom6.add(10, 10);
-
- // Create
- ListeningGeometryCursor gc = new ListeningGeometryCursor();
- GeometryCursor ticktock = OperatorConvexHull.local().execute(gc, true, null);
-
- // Use tick-tock to push a geometry and do a piece of work.
- gc.tick(geom1);
- ticktock.tock();
- gc.tick(geom2);
- ticktock.tock();
- gc.tick(geom3);// skiped one tock just for testing.
- ticktock.tock();
- gc.tick(geom4);
- ticktock.tock();
- gc.tick(geom5);
- ticktock.tock();
- gc.tick(geom6);
- ticktock.tock();
- // Get the result
- Geometry result = ticktock.next();
- Polygon convex_hull = (Polygon)result;
- assertTrue(OperatorConvexHull.local().isConvex(convex_hull, null));
-
- Point2D p1 = convex_hull.getXY(0);
- Point2D p2 = convex_hull.getXY(1);
- Point2D p3 = convex_hull.getXY(2);
- Point2D p4 = convex_hull.getXY(3);
- Point2D p5 = convex_hull.getXY(4);
- Point2D p6 = convex_hull.getXY(5);
- assertTrue(p1.x == 5.0 && p1.y == 11.0);
- assertTrue(p2.x == 10.0 && p2.y == 10);
- assertTrue(p3.x == 15.0 && p3.y == 1.25);
- assertTrue(p4.x == 5.0 && p4.y == -5.0);
- assertTrue(p5.x == -5.0 && p5.y == 1.25);
- assertTrue(p6.x == 0.0 && p6.y == 10.0);
- }
-
-}
diff --git a/unittest/com/esri/core/geometry/TestGeodetic.java b/unittest/com/esri/core/geometry/TestGeodetic.java
deleted file mode 100644
index 0c788cc2..00000000
--- a/unittest/com/esri/core/geometry/TestGeodetic.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.esri.core.geometry;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestGeodetic extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public static void testTriangleLength() {
- Point pt_0 = new Point(10, 10);
- Point pt_1 = new Point(20, 20);
- Point pt_2 = new Point(20, 10);
- double length = 0.0;
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_0, pt_1);
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_1, pt_2);
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_2, pt_0);
- assertTrue(Math.abs(length - 3744719.4094597572) < 1e-13 * 3744719.4094597572);
- }
-
- @Test
- public static void testRotationInvariance() {
- Point pt_0 = new Point(10, 40);
- Point pt_1 = new Point(20, 60);
- Point pt_2 = new Point(20, 40);
- double length = 0.0;
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_0, pt_1);
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_1, pt_2);
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_2, pt_0);
- assertTrue(Math.abs(length - 5409156.3896271614) < 1e-13 * 5409156.3896271614);
-
- for (int i = -540; i < 540; i += 5) {
- pt_0.setXY(i + 10, 40);
- pt_1.setXY(i + 20, 60);
- pt_2.setXY(i + 20, 40);
- length = 0.0;
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_0, pt_1);
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_1, pt_2);
- length += GeometryEngine.geodesicDistanceOnWGS84(pt_2, pt_0);
- assertTrue(Math.abs(length - 5409156.3896271614) < 1e-13 * 5409156.3896271614);
- }
- }
-
- @Test
- public static void testLengthAccurateCR191313() {
- /*
- * // random_test(); OperatorFactoryLocal engine =
- * OperatorFactoryLocal.getInstance(); //TODO: Make this:
- * OperatorShapePreservingLength geoLengthOp =
- * (OperatorShapePreservingLength)
- * factory.getOperator(Operator.Type.ShapePreservingLength);
- * SpatialReference spatialRef = SpatialReference.create(102631);
- * //[6097817.59407673
- * ,17463475.2931517],[-1168053.34617516,11199801.3734424
- * ]]],"spatialReference":{"wkid":102631}
- *
- * Polyline polyline = new Polyline();
- * polyline.startPath(6097817.59407673, 17463475.2931517);
- * polyline.lineTo(-1168053.34617516, 11199801.3734424); double length =
- * geoLengthOp.execute(polyline, spatialRef, null);
- * assertTrue(Math.abs(length - 2738362.3249366437) < 2e-9 * length);
- */
- }
-
}
diff --git a/unittest/com/esri/core/geometry/TestGeomToGeoJson.java b/unittest/com/esri/core/geometry/TestGeomToGeoJson.java
deleted file mode 100644
index 80099069..00000000
--- a/unittest/com/esri/core/geometry/TestGeomToGeoJson.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- Licensed 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.
-
- For additional information, contact:
- Environmental Systems Research Institute, Inc.
- Attn: Contracts Dept
- 380 New York Street
- Redlands, California, USA 92373
-
- email: contracts@esri.com
- */
-
-package com.esri.core.geometry;
-
-import com.esri.core.geometry.ogc.OGCGeometry;
-import com.esri.core.geometry.ogc.OGCPoint;
-import com.esri.core.geometry.ogc.OGCMultiPoint;
-import com.esri.core.geometry.ogc.OGCLineString;
-import com.esri.core.geometry.ogc.OGCPolygon;
-import junit.framework.TestCase;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParser;
-import org.json.JSONException;
-import org.junit.Test;
-
-import java.io.IOException;
-
-public class TestGeomToGeoJson extends TestCase {
- OperatorFactoryLocal factory = OperatorFactoryLocal.getInstance();
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public void testPoint() {
- Point p = new Point(10.0, 20.0);
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"Point\",\"coordinates\":[10.0,20.0]}", result);
- }
-
- @Test
- public void testEmptyPoint() {
- Point p = new Point();
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"Point\",\"coordinates\":null}", result);
- }
-
- @Test
- public void testPointGeometryEngine() {
- Point p = new Point(10.0, 20.0);
- String result = GeometryEngine.geometryToGeoJson(p);
- assertEquals("{\"type\":\"Point\",\"coordinates\":[10.0,20.0]}", result);
- }
-
- @Test
- public void testOGCPoint() {
- Point p = new Point(10.0, 20.0);
- OGCGeometry ogcPoint = new OGCPoint(p, null);
- String result = ogcPoint.asGeoJson();
- assertEquals("{\"type\":\"Point\",\"coordinates\":[10.0,20.0]}", result);
- }
-
- @Test
- public void testMultiPoint() {
- MultiPoint mp = new MultiPoint();
- mp.add(10.0, 20.0);
- mp.add(20.0, 30.0);
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(mp);
- assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[10.0,20.0],[20.0,30.0]]}", result);
- }
-
- @Test
- public void testEmptyMultiPoint() {
- MultiPoint mp = new MultiPoint();
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(mp);
- assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":null}", result);
- }
-
- @Test
- public void testMultiPointGeometryEngine() {
- MultiPoint mp = new MultiPoint();
- mp.add(10.0, 20.0);
- mp.add(20.0, 30.0);
- String result = GeometryEngine.geometryToGeoJson(mp);
- assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[10.0,20.0],[20.0,30.0]]}", result);
- }
-
- @Test
- public void testOGCMultiPoint() {
- MultiPoint mp = new MultiPoint();
- mp.add(10.0, 20.0);
- mp.add(20.0, 30.0);
- OGCMultiPoint ogcMultiPoint = new OGCMultiPoint(mp, null);
- String result = ogcMultiPoint.asGeoJson();
- assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[10.0,20.0],[20.0,30.0]]}", result);
- }
-
- @Test
- public void testPolyline() {
- Polyline p = new Polyline();
- p.startPath(100.0, 0.0);
- p.lineTo(101.0, 0.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(100.0, 1.0);
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0]]}", result);
- }
-
- @Test
- public void testEmptyPolyline() {
- Polyline p = new Polyline();
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"LineString\",\"coordinates\":null}", result);
- }
-
- @Test
- public void testPolylineGeometryEngine() {
- Polyline p = new Polyline();
- p.startPath(100.0, 0.0);
- p.lineTo(101.0, 0.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(100.0, 1.0);
- String result = GeometryEngine.geometryToGeoJson(p);
- assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0]]}", result);
- }
-
- @Test
- public void testOGCLineString() {
- Polyline p = new Polyline();
- p.startPath(100.0, 0.0);
- p.lineTo(101.0, 0.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(100.0, 1.0);
- OGCLineString ogcLineString = new OGCLineString(p, 0, null);
- String result = ogcLineString.asGeoJson();
- assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0]]}", result);
- }
-
- @Test
- public void testPolygon() {
- Polygon p = new Polygon();
- p.startPath(100.0, 0.0);
- p.lineTo(101.0, 0.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(100.0, 1.0);
- p.closePathWithLine();
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]]]}", result);
- }
-
- @Test
- public void testPolygonWithHole() {
- Polygon p = new Polygon();
-
- //exterior ring - has to be clockwise for Esri
- p.startPath(100.0, 0.0);
- p.lineTo(100.0, 1.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(101.0, 0.0);
- p.closePathWithLine();
-
- //hole - counterclockwise for Esri
- p.startPath(100.2, 0.2);
- p.lineTo(100.8, 0.2);
- p.lineTo(100.8, 0.8);
- p.lineTo(100.2, 0.8);
- p.closePathWithLine();
-
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[100.0,1.0],[101.0,1.0],[101.0,0.0],[100.0,0.0]],[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]}", result);
- }
-
- @Test
- public void testPolygonWithHoleReversed() {
- Polygon p = new Polygon();
-
- //exterior ring - has to be clockwise for Esri
- p.startPath(100.0, 0.0);
- p.lineTo(100.0, 1.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(101.0, 0.0);
- p.closePathWithLine();
-
- //hole - counterclockwise for Esri
- p.startPath(100.2, 0.2);
- p.lineTo(100.8, 0.2);
- p.lineTo(100.8, 0.8);
- p.lineTo(100.2, 0.8);
- p.closePathWithLine();
-
- p.reverseAllPaths();//make it reversed. Exterior ring - ccw, hole - cw.
-
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],[[100.2,0.2],[100.2,0.8],[100.8,0.8],[100.8,0.2],[100.2,0.2]]]}", result);
- }
-
- @Test
- public void testMultiPolygon() throws IOException {
- JsonFactory jsonFactory = new JsonFactory();
-
- String geoJsonPolygon = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-100.0,-100.0],[-100.0,100.0],[100.0,100.0],[100.0,-100.0],[-100.0,-100.0]],[[-90.0,-90.0],[90.0,90.0],[-90.0,90.0],[90.0,-90.0],[-90.0,-90.0]]],[[[-10.0,-10.0],[-10.0,10.0],[10.0,10.0],[10.0,-10.0],[-10.0,-10.0]]]]}";
- String esriJsonPolygon = "{\"rings\": [[[-100, -100], [-100, 100], [100, 100], [100, -100], [-100, -100]], [[-90, -90], [90, 90], [-90, 90], [90, -90], [-90, -90]], [[-10, -10], [-10, 10], [10, 10], [10, -10], [-10, -10]]]}";
-
- JsonParser parser = jsonFactory.createJsonParser(esriJsonPolygon);
- MapGeometry parsedPoly = GeometryEngine.jsonToGeometry(parser);
- //MapGeometry parsedPoly = GeometryEngine.geometryFromGeoJson(jsonPolygon, 0, Geometry.Type.Polygon);
-
- Polygon poly = (Polygon) parsedPoly.getGeometry();
-
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- //String result = exporter.execute(parsedPoly.getGeometry());
- String result = exporter.execute(poly);
- assertEquals(geoJsonPolygon, result);
- }
-
-
-
- @Test
- public void testEmptyPolygon() throws JSONException {
- Polygon p = new Polygon();
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(p);
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":null}", result);
-
- MapGeometry imported = OperatorImportFromGeoJson.local().execute(0, Geometry.Type.Unknown, result, null);
- assertTrue(imported.getGeometry().isEmpty());
- assertTrue(imported.getGeometry().getType() == Geometry.Type.Polygon);
- }
-
- @Test
- public void testPolygonGeometryEngine() {
- Polygon p = new Polygon();
- p.startPath(100.0, 0.0);
- p.lineTo(101.0, 0.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(100.0, 1.0);
- p.closePathWithLine();
- String result = GeometryEngine.geometryToGeoJson(p);
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]]]}", result);
- }
-
- @Test
- public void testOGCPolygon() {
- Polygon p = new Polygon();
- p.startPath(100.0, 0.0);
- p.lineTo(101.0, 0.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(100.0, 1.0);
- p.closePathWithLine();
- OGCPolygon ogcPolygon = new OGCPolygon(p, null);
- String result = ogcPolygon.asGeoJson();
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]]]}", result);
- }
-
- @Test
- public void testPolygonWithHoleGeometryEngine() {
- Polygon p = new Polygon();
-
- p.startPath(100.0, 0.0);//clockwise exterior
- p.lineTo(100.0, 1.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(101.0, 0.0);
- p.closePathWithLine();
-
- p.startPath(100.2, 0.2);//counterclockwise hole
- p.lineTo(100.8, 0.2);
- p.lineTo(100.8, 0.8);
- p.lineTo(100.2, 0.8);
- p.closePathWithLine();
-
- String result = GeometryEngine.geometryToGeoJson(p);
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[100.0,1.0],[101.0,1.0],[101.0,0.0],[100.0,0.0]],[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]}", result);
- }
-
- @Test
- public void testPolylineWithTwoPaths() {
- Polyline p = new Polyline();
-
- p.startPath(100.0, 0.0);
- p.lineTo(100.0, 1.0);
-
- p.startPath(100.2, 0.2);
- p.lineTo(100.8, 0.2);
-
- String result = GeometryEngine.geometryToGeoJson(p);
- assertEquals("{\"type\":\"MultiLineString\",\"coordinates\":[[[100.0,0.0],[100.0,1.0]],[[100.2,0.2],[100.8,0.2]]]}", result);
- }
-
- @Test
- public void testOGCPolygonWithHole() {
- Polygon p = new Polygon();
-
- p.startPath(100.0, 0.0);
- p.lineTo(100.0, 1.0);
- p.lineTo(101.0, 1.0);
- p.lineTo(101.0, 0.0);
- p.closePathWithLine();
-
- p.startPath(100.2, 0.2);
- p.lineTo(100.8, 0.2);
- p.lineTo(100.8, 0.8);
- p.lineTo(100.2, 0.8);
- p.closePathWithLine();
-
- OGCPolygon ogcPolygon = new OGCPolygon(p, null);
- String result = ogcPolygon.asGeoJson();
- assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[100.0,1.0],[101.0,1.0],[101.0,0.0],[100.0,0.0]],[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]}", result);
- }
-
- @Test
- public void testEnvelope() {
- Envelope e = new Envelope();
- e.setCoords(-180.0, -90.0, 180.0, 90.0);
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(e);
- assertEquals("{\"bbox\":[-180.0,-90.0,180.0,90.0]}", result);
- }
-
- @Test
- public void testEmptyEnvelope() {
- Envelope e = new Envelope();
- OperatorExportToGeoJson exporter = (OperatorExportToGeoJson) factory.getOperator(Operator.Type.ExportToGeoJson);
- String result = exporter.execute(e);
- assertEquals("{\"bbox\":null}", result);
- }
-
- @Test
- public void testEnvelopeGeometryEngine() {
- Envelope e = new Envelope();
- e.setCoords(-180.0, -90.0, 180.0, 90.0);
- String result = GeometryEngine.geometryToGeoJson(e);
- assertEquals("{\"bbox\":[-180.0,-90.0,180.0,90.0]}", result);
- }
-
-}
diff --git a/unittest/com/esri/core/geometry/TestQuadTree.java b/unittest/com/esri/core/geometry/TestQuadTree.java
deleted file mode 100644
index adca5ac6..00000000
--- a/unittest/com/esri/core/geometry/TestQuadTree.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package com.esri.core.geometry;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestQuadTree extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public static void test1() {
- Polyline polyline;
- polyline = makePolyline();
-
- MultiPathImpl polylineImpl = (MultiPathImpl) polyline._getImpl();
- QuadTree quadtree = buildQuadTree_(polylineImpl);
-
- Line queryline = new Line(34, 9, 66, 46);
- QuadTree.QuadTreeIterator qtIter = quadtree.getIterator();
- assertTrue(qtIter.next() == -1);
-
- qtIter.resetIterator(queryline, 0.0);
-
- int element_handle = qtIter.next();
- while (element_handle > 0) {
- int index = quadtree.getElement(element_handle);
- assertTrue(index == 6 || index == 8 || index == 14);
- element_handle = qtIter.next();
- }
- }
-
- @Test
- public static void test2() {
- MultiPoint multipoint = new MultiPoint();
-
- for (int i = 0; i < 100; i++) {
- for (int j = 0; j < 100; j++) {
- multipoint.add(i, j);
- }
- }
-
- Envelope2D extent = new Envelope2D();
- multipoint.queryEnvelope2D(extent);
-
- MultiPointImpl multipointImpl = (MultiPointImpl) multipoint._getImpl();
- QuadTree quadtree = buildQuadTree_(multipointImpl);
-
- QuadTree.QuadTreeIterator qtIter = quadtree.getIterator();
- assertTrue(qtIter.next() == -1);
-
- int count = 0;
- qtIter.resetIterator(extent, 0.0);
-
- while (qtIter.next() != -1) {
- count++;
- }
-
- assertTrue(count == 10000);
- }
-
- public static Polyline makePolyline() {
- Polyline poly = new Polyline();
-
- // 0
- poly.startPath(0, 40);
- poly.lineTo(30, 0);
-
- // 1
- poly.startPath(20, 70);
- poly.lineTo(45, 100);
-
- // 2
- poly.startPath(50, 100);
- poly.lineTo(50, 60);
-
- // 3
- poly.startPath(35, 25);
- poly.lineTo(65, 45);
-
- // 4
- poly.startPath(60, 10);
- poly.lineTo(65, 35);
-
- // 5
- poly.startPath(60, 60);
- poly.lineTo(100, 60);
-
- // 6
- poly.startPath(80, 10);
- poly.lineTo(80, 99);
-
- // 7
- poly.startPath(60, 60);
- poly.lineTo(65, 35);
-
- return poly;
- }
-
- static QuadTree buildQuadTree_(MultiPathImpl multipathImpl) {
- Envelope2D extent = new Envelope2D();
- multipathImpl.queryEnvelope2D(extent);
- QuadTree quadTree = new QuadTree(extent, 8);
- int hint_index = -1;
- Envelope2D boundingbox = new Envelope2D();
- SegmentIteratorImpl seg_iter = multipathImpl.querySegmentIterator();
- while (seg_iter.nextPath()) {
- while (seg_iter.hasNextSegment()) {
- Segment segment = seg_iter.nextSegment();
- int index = seg_iter.getStartPointIndex();
- segment.queryEnvelope2D(boundingbox);
- hint_index = quadTree.insert(index, boundingbox, hint_index);
- }
- }
-
- return quadTree;
- }
-
- static QuadTree buildQuadTree_(MultiPointImpl multipointImpl) {
- Envelope2D extent = new Envelope2D();
- multipointImpl.queryEnvelope2D(extent);
- QuadTree quadTree = new QuadTree(extent, 8);
- Envelope2D boundingbox = new Envelope2D();
- Point2D pt;
-
- for (int i = 0; i < multipointImpl.getPointCount(); i++) {
- pt = multipointImpl.getXY(i);
- boundingbox.setCoords(pt.x, pt.y, pt.x, pt.y);
- quadTree.insert(i, boundingbox, -1);
- }
-
- return quadTree;
- }
-}
diff --git a/unittest/com/esri/core/geometry/TestSerialization.java b/unittest/com/esri/core/geometry/TestSerialization.java
deleted file mode 100644
index 27587c34..00000000
--- a/unittest/com/esri/core/geometry/TestSerialization.java
+++ /dev/null
@@ -1,294 +0,0 @@
-package com.esri.core.geometry;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestSerialization extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public void testSerializePoint() {
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- Point pt = new Point(10, 40);
- oo.writeObject(pt);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- Point ptRes = (Point) ii.readObject();
- assertTrue(ptRes.equals(pt));
- } catch (Exception ex) {
- fail("Point serialization failure");
-
- }
-
- // try
- // {
- // FileOutputStream streamOut = new FileOutputStream(m_thisDirectory +
- // "savedPoint.txt");
- // ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- // Point pt = new Point(10, 40);
- // oo.writeObject(pt);
- // }
- // catch(Exception ex)
- // {
- // fail("Point serialization failure");
- // }
-
- try {
- InputStream s = TestSerialization.class
- .getResourceAsStream("savedPoint.txt");
- ObjectInputStream ii = new ObjectInputStream(s);
- Point ptRes = (Point) ii.readObject();
- assertTrue(ptRes.getX() == 10 && ptRes.getY() == 40);
- } catch (Exception ex) {
- fail("Point serialization failure");
- }
- }
-
- @Test
- public void testSerializePolygon() {
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- Polygon pt = new Polygon();
- pt.startPath(10, 10);
- pt.lineTo(100, 100);
- pt.lineTo(200, 100);
- oo.writeObject(pt);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- Polygon ptRes = (Polygon) ii.readObject();
- assertTrue(ptRes.equals(pt));
- } catch (Exception ex) {
- fail("Polygon serialization failure");
- }
-
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- Polygon pt = new Polygon();
- pt.startPath(10, 10);
- pt.lineTo(100, 100);
- pt.lineTo(200, 100);
- pt = (Polygon) GeometryEngine.simplify(pt, null);
- oo.writeObject(pt);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- Polygon ptRes = (Polygon) ii.readObject();
- assertTrue(ptRes.equals(pt));
- } catch (Exception ex) {
- fail("Polygon serialization failure");
- }
-
- // try
- // {
- // FileOutputStream streamOut = new FileOutputStream(m_thisDirectory +
- // "savedPolygon.txt");
- // ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- // Polygon pt = new Polygon();
- // pt.startPath(10, 10);
- // pt.lineTo(100, 100);
- // pt.lineTo(200, 100);
- // pt = (Polygon)GeometryEngine.simplify(pt, null);
- // oo.writeObject(pt);
- // }
- // catch(Exception ex)
- // {
- // fail("Polygon serialization failure");
- // }
-
- try {
- InputStream s = TestSerialization.class
- .getResourceAsStream("savedPolygon.txt");
- ObjectInputStream ii = new ObjectInputStream(s);
- Polygon ptRes = (Polygon) ii.readObject();
- assertTrue(ptRes != null);
- } catch (Exception ex) {
- fail("Polygon serialization failure");
- }
- }
-
- @Test
- public void testSerializePolyline() {
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- Polyline pt = new Polyline();
- pt.startPath(10, 10);
- pt.lineTo(100, 100);
- pt.lineTo(200, 100);
- oo.writeObject(pt);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- Polyline ptRes = (Polyline) ii.readObject();
- assertTrue(ptRes.equals(pt));
- } catch (Exception ex) {
- fail("Polyline serialization failure");
- }
-
- // try
- // {
- // FileOutputStream streamOut = new FileOutputStream(m_thisDirectory +
- // "savedPolyline.txt");
- // ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- // Polyline pt = new Polyline();
- // pt.startPath(10, 10);
- // pt.lineTo(100, 100);
- // pt.lineTo(200, 100);
- // oo.writeObject(pt);
- // }
- // catch(Exception ex)
- // {
- // fail("Polyline serialization failure");
- // }
-
- try {
- InputStream s = TestSerialization.class
- .getResourceAsStream("savedPolyline.txt");
- ObjectInputStream ii = new ObjectInputStream(s);
- Polyline ptRes = (Polyline) ii.readObject();
- assertTrue(ptRes != null);
- } catch (Exception ex) {
- fail("Polyline serialization failure");
- }
- }
-
- @Test
- public void testSerializeEnvelope() {
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- Envelope pt = new Envelope(10, 10, 400, 300);
- oo.writeObject(pt);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- Envelope ptRes = (Envelope) ii.readObject();
- assertTrue(ptRes.equals(pt));
- } catch (Exception ex) {
- fail("Envelope serialization failure");
- }
-
- // try
- // {
- // FileOutputStream streamOut = new FileOutputStream(m_thisDirectory +
- // "savedEnvelope.txt");
- // ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- // Envelope pt = new Envelope(10, 10, 400, 300);
- // oo.writeObject(pt);
- // }
- // catch(Exception ex)
- // {
- // fail("Envelope serialization failure");
- // }
-
- try {
- InputStream s = TestSerialization.class
- .getResourceAsStream("savedEnvelope.txt");
- ObjectInputStream ii = new ObjectInputStream(s);
- Envelope ptRes = (Envelope) ii.readObject();
- assertTrue(ptRes.getXMax() == 400);
- } catch (Exception ex) {
- fail("Envelope serialization failure");
- }
- }
-
- @Test
- public void testSerializeMultiPoint() {
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- MultiPoint pt = new MultiPoint();
- pt.add(10, 30);
- pt.add(120, 40);
- oo.writeObject(pt);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- MultiPoint ptRes = (MultiPoint) ii.readObject();
- assertTrue(ptRes.equals(pt));
- } catch (Exception ex) {
- fail("MultiPoint serialization failure");
- }
-
- // try
- // {
- // FileOutputStream streamOut = new FileOutputStream(m_thisDirectory +
- // "savedMultiPoint.txt");
- // ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- // MultiPoint pt = new MultiPoint();
- // pt.add(10, 30);
- // pt.add(120, 40);
- // oo.writeObject(pt);
- // }
- // catch(Exception ex)
- // {
- // fail("MultiPoint serialization failure");
- // }
-
- try {
- InputStream s = TestSerialization.class
- .getResourceAsStream("savedMultiPoint.txt");
- ObjectInputStream ii = new ObjectInputStream(s);
- MultiPoint ptRes = (MultiPoint) ii.readObject();
- assertTrue(ptRes.getPoint(1).getY() == 40);
- } catch (Exception ex) {
- fail("MultiPoint serialization failure");
- }
- }
-
- @Test
- public void testSerializeLine() {
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- Line pt = new Line();
- pt.setStart(new Point(10, 30));
- pt.setEnd(new Point(120, 40));
- oo.writeObject(pt);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- Line ptRes = (Line) ii.readObject();
- assertTrue(ptRes.equals(pt));
- } catch (Exception ex) {
- // fail("Line serialization failure");
- assertEquals(ex.getMessage(), "Cannot serialize this geometry");
- }
- }
-
- @Test
- public void testSerializeSR() {
- try {
- ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(streamOut);
- SpatialReference sr = SpatialReference.create(102100);
- oo.writeObject(sr);
- ByteArrayInputStream streamIn = new ByteArrayInputStream(
- streamOut.toByteArray());
- ObjectInputStream ii = new ObjectInputStream(streamIn);
- SpatialReference ptRes = (SpatialReference) ii.readObject();
- assertTrue(ptRes.equals(sr));
- } catch (Exception ex) {
- fail("Spatial Reference serialization failure");
- }
- }
-
}
diff --git a/unittest/com/esri/core/geometry/TestShapePreserving.java b/unittest/com/esri/core/geometry/TestShapePreserving.java
deleted file mode 100644
index 0d5524e5..00000000
--- a/unittest/com/esri/core/geometry/TestShapePreserving.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package com.esri.core.geometry;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestShapePreserving extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public static void testBoxAreasWithinToleranceCR186615() {
- /*
- * //TODO: Implement these OperatorShapePreservingArea shapeAreaOp =
- * OperatorShapePreservingArea.local(); OperatorShapePreservingLength
- * shapeLengthOp = OperatorShapePreservingLength.local();
- *
- * Polyline polyline2 = new Polyline(); polyline2.startPath(190, 0);
- * polyline2.lineTo(200,0); SpatialReference spatialRefWGS =
- * SpatialReference.create(4326); double lengthEquator10Degree =
- * shapeLengthOp.execute(polyline2, spatialRefWGS, null);
- * assertTrue(lengthEquator10Degree != 0.00);
- *
- * Polyline polylineEquator2 = new Polyline();
- * polylineEquator2.startPath(170, 0); polylineEquator2.lineTo(180,0);
- * double lengthEquator10Degree2 =
- * shapeLengthOp.execute(polylineEquator2, spatialRefWGS, null);
- * assertTrue(GeomCommonMethods.compareDouble(lengthEquator10Degree2,
- * lengthEquator10Degree, Math.pow(10.0,-10)));
- *
- * SpatialReference spatialRefWGSMerc = SpatialReference.create(102100);
- * double PCS5 = 111319.49079327358 * 5; double PCS180 =
- * 20037508.342789244; double CSYMax = 30240970.0; double CSYMin =
- * -30240970.0;
- *
- * Polyline polylineEquator3 = new Polyline();
- * polylineEquator3.startPath(-PCS180 - 4*PCS5, 0);
- * polylineEquator3.lineTo(-PCS180 - 2*PCS5, 0); double
- * lengthEquatorMercDegree = shapeLengthOp.execute(*polylineEquator3,
- * spatialRefWGSMerc, null);
- * assertTrue(GeomCommonMethods.compareDouble(lengthEquatorMercDegree,
- * lengthEquator10Degree, Math.pow(10.0,-10)));
- *
- * Polyline polylineBox = new Polyline(); polylineBox.startPath(PCS180 -
- * 2*PCS5, 30240970.0 / 9); polylineBox.lineTo(PCS180 + 2*PCS5,
- * 30240970.0 / 9); polylineBox.lineTo(PCS180 + 2*PCS5, -30240970.0 /
- * 9); polylineBox.lineTo(PCS180 - 2*PCS5, -30240970.0 / 9);
- * polylineBox.lineTo(PCS180 - 2*PCS5, 30240970.0 / 9);
- *
- * Polygon polygonBox = new Polygon(); polygonBox.startPath(PCS180 -
- * 2*PCS5, 30240970.0 / 9); polygonBox.lineTo(PCS180 + 2*PCS5,
- * 30240970.0 / 9); polygonBox.lineTo(PCS180 + 2*PCS5, -30240970.0 / 9);
- * polygonBox.lineTo(PCS180 - 2*PCS5, -30240970.0 / 9);
- * polygonBox.lineTo(PCS180 - 2*PCS5, 30240970.0 / 9);
- *
- * Envelope envelopeBox = new Envelope();
- * polygonBox.queryEnvelope(envelopeBox);
- *
- * double lengthBox1 = shapeLengthOp.execute(polylineBox,
- * spatialRefWGSMerc, null); double lengthBox2 =
- * shapeLengthOp.execute(polygonBox, spatialRefWGSMerc, null); double
- * lengthBox3 = shapeLengthOp.execute(envelopeBox, spatialRefWGSMerc,
- * null); assertTrue(GeomCommonMethods.compareDouble(lengthBox1,
- * lengthBox2, Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(lengthBox1, lengthBox3,
- * Math.pow(10.0,-10)));
- *
- * // Repeated polygon area Polygon polygonBox1 = new Polygon();
- * polygonBox1.startPath(-PCS180 - 6 * PCS5, 30240970.0 / 9);
- * polygonBox1.lineTo(-PCS180 - 4 * PCS5, 30240970.0 / 9);
- * polygonBox1.lineTo(-PCS180 - 4 * PCS5, -30240970.0 / 9);
- * polygonBox1.lineTo(-PCS180 - 6 * PCS5, -30240970.0 / 9);
- *
- * Polygon polygonBox2 = new Polygon(); polygonBox2.startPath(-PCS180 -
- * 2 * PCS5, 30240970.0 / 9); polygonBox2.lineTo(-PCS180, 30240970.0 /
- * 9); polygonBox2.lineTo(-PCS180, -30240970.0 / 9);
- * polygonBox2.lineTo(-PCS180 - 2 * PCS5, -30240970.0 / 9);
- *
- * Polygon polygonBox3 = new Polygon(); polygonBox3.startPath(-PCS180 -
- * PCS5, 30240970.0 / 9); polygonBox3.lineTo(-PCS180 + PCS5, 30240970.0
- * / 9); polygonBox3.lineTo(-PCS180 + PCS5, -30240970.0 / 9);
- * polygonBox3.lineTo(-PCS180 - PCS5, -30240970.0 / 9);
- *
- * Polygon polygonBox4 = new Polygon(); polygonBox4.startPath(-PCS180,
- * 30240970.0 / 9); polygonBox4.lineTo(-PCS180 + 2 * PCS5, 30240970.0 /
- * 9); polygonBox4.lineTo(-PCS180 + 2 * PCS5, -30240970.0 / 9);
- * polygonBox4.lineTo(-PCS180, -30240970.0 / 9);
- *
- * Polygon polygonBox5 = new Polygon(); polygonBox5.startPath(PCS180 - 6
- * * PCS5, 30240970.0 / 9); polygonBox5.lineTo(PCS180 - 4 * PCS5,
- * 30240970.0 / 9); polygonBox5.lineTo(PCS180 - 4 * PCS5, -30240970.0 /
- * 9); polygonBox5.lineTo(PCS180 - 6 * PCS5, -30240970.0 / 9);
- *
- * Polygon polygonBox6 = new Polygon(); polygonBox6.startPath(PCS180 - 2
- * * PCS5, 30240970.0 / 9); polygonBox6.lineTo(PCS180, 30240970.0 / 9);
- * polygonBox6.lineTo(PCS180, -30240970.0 / 9);
- * polygonBox6.lineTo(PCS180 - 2 * PCS5, -30240970.0 / 9);
- *
- * Polygon polygonBox7 = new Polygon(); polygonBox7.startPath(PCS180 -
- * PCS5, 30240970.0 / 9); polygonBox7.lineTo(PCS180 + PCS5, 30240970.0 /
- * 9); polygonBox7.lineTo(PCS180 + PCS5, -30240970.0 / 9);
- * polygonBox7.lineTo(PCS180 - PCS5, -30240970.0 / 9);
- *
- * Polygon polygonBox8 = new Polygon(); polygonBox8.startPath(PCS180,
- * 30240970.0 / 9); polygonBox8.lineTo(PCS180 + 2 * PCS5, 30240970.0 /
- * 9); polygonBox8.lineTo(PCS180 + 2 * PCS5, -30240970.0 / 9);
- * polygonBox8.lineTo(PCS180, -30240970.0 / 9);
- *
- * Polygon polygonBox9 = new Polygon(); polygonBox9.startPath(PCS180 + 2
- * * PCS5, 30240970.0 / 9); polygonBox9.lineTo(PCS180 + 4 * PCS5,
- * 30240970.0 / 9); polygonBox9.lineTo(PCS180 + 4 * PCS5, -30240970.0 /
- * 9); polygonBox9.lineTo(PCS180 + 2 * PCS5, -30240970.0 / 9);
- *
- * double area1 = shapeAreaOp.execute(polygonBox1, spatialRefWGSMerc,
- * null); double area2 = shapeAreaOp.execute(polygonBox2,
- * spatialRefWGSMerc, null); double area3 =
- * shapeAreaOp.execute(polygonBox3, spatialRefWGSMerc, null); double
- * area4 = shapeAreaOp.execute(polygonBox4, spatialRefWGSMerc, null);
- * double area5 = shapeAreaOp.execute(polygonBox5, spatialRefWGSMerc,
- * null); double area6 = shapeAreaOp.execute(polygonBox6,
- * spatialRefWGSMerc, null); double area7 =
- * shapeAreaOp.execute(polygonBox7, spatialRefWGSMerc, null); double
- * area8 = shapeAreaOp.execute(polygonBox8, spatialRefWGSMerc, null);
- * double area9 = shapeAreaOp.execute(polygonBox9, spatialRefWGSMerc,
- * null);
- *
- * assertTrue(GeomCommonMethods.compareDouble(area1, area2,
- * Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(area1, area3,
- * Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(area1, area4,
- * Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(area1, area5,
- * Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(area1, area6,
- * Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(area1, area7,
- * Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(area1, area8,
- * Math.pow(10.0,-10)));
- * assertTrue(GeomCommonMethods.compareDouble(area1, area9,
- * Math.pow(10.0,-10)));
- */
- }
-}
diff --git a/unittest/com/esri/core/geometry/TestUnion.java b/unittest/com/esri/core/geometry/TestUnion.java
deleted file mode 100644
index 94f3ef86..00000000
--- a/unittest/com/esri/core/geometry/TestUnion.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.esri.core.geometry;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-public class TestUnion extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public static void testUnion() {
- Point pt = new Point(10, 20);
- System.out.println(pt.getX());
-
- Point pt2 = new Point();
- pt2.setXY(10, 10);
-
- Envelope env1 = new Envelope(10, 10, 30, 50);
- Envelope env2 = new Envelope(30, 10, 60, 50);
- Geometry[] geomArray = new Geometry[] { env1, env2 };
- SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(
- geomArray);
- OperatorUnion union = (OperatorUnion) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Union);
-
- SpatialReference sr = SpatialReference.create(4326);
-
- GeometryCursor outputCursor = union.execute(inputGeometries, sr, null);
- Geometry result = outputCursor.next();
- System.out.println(result);
- }
-}
diff --git a/unittest/com/esri/core/geometry/TestWKBSupport.java b/unittest/com/esri/core/geometry/TestWKBSupport.java
deleted file mode 100644
index 656765d8..00000000
--- a/unittest/com/esri/core/geometry/TestWKBSupport.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package com.esri.core.geometry;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import junit.framework.TestCase;
-import org.junit.Test;
-
-//import com.vividsolutions.jts.io.WKBReader;
-
-public class TestWKBSupport extends TestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Test
- public void testWKB() {
- try {
- // JSON -> GEOM -> WKB
-
- String strPolygon1 = "{\"xmin\":-1.1663479012889031E7,\"ymin\":4919777.494405342,\"xmax\":-1.1658587043078788E7,\"ymax\":4924669.464215587,\"spatialReference\":{\"wkid\":102100}}";
- // String strPolygon1 =
- // "{\"rings\":[[[-119.152450421001,38.4118009590513],[-119.318825070203,38.5271086243914],[-119.575687062955,38.7029101298904],[-119.889341639399,38.9222515603984],[-119.995254694357,38.9941061536377],[-119.995150114198,39.0634913594691],[-119.994541258334,39.1061318056708],[-119.995527335641,39.1587132866355],[-119.995304181493,39.3115454332125],[-119.996011479298,39.4435009764511],[-119.996165311172,39.7206108077274],[-119.996324660047,41.1775662656441],[-119.993459369715,41.9892049531992],[-119.351692186077,41.9888529749781],[-119.3109421304,41.9891353872811],[-118.185316829038,41.9966370981387],[-117.018864363596,41.9947941808341],[-116.992313337997,41.9947945094663],[-115.947544658193,41.9945994628997],[-115.024862911148,41.996506455953],[-114.269471632824,41.9959242345073],[-114.039072662345,41.9953908974688],[-114.038151248682,40.9976868405942],[-114.038108189376,40.1110466529553],[-114.039844684228,39.9087788600023],[-114.040105338584,39.5386849268845],[-114.044267501155,38.6789958815881],[-114.045090206153,38.5710950539539],[-114.047272999176,38.1376524399918],[-114.047260595159,37.5984784866001],[-114.043939384154,36.9965379371421],[-114.043716435713,36.8418489458647],[-114.037392074194,36.2160228969702],[-114.045105557286,36.1939778840226],[-114.107775185788,36.1210907070504],[-114.12902308363,36.041730493896],[-114.206768869568,36.0172554164834],[-114.233472615347,36.0183310595897],[-114.307587598189,36.0622330993643],[-114.303857056018,36.0871084040611],[-114.316095374696,36.1114380366653],[-114.344233941709,36.1374802520568],[-114.380803116644,36.1509912717765],[-114.443945697733,36.1210532841897],[-114.466613475422,36.1247112590539],[-114.530573568745,36.1550902046725],[-114.598935242024,36.1383354528834],[-114.621610747198,36.1419666834504],[-114.712761724737,36.1051810523675],[-114.728150311069,36.0859627711604],[-114.728966012834,36.0587530361083],[-114.717673567756,36.0367580437018],[-114.736212493583,35.9876483502758],[-114.699275906446,35.9116119537412],[-114.661600122152,35.8804735854242],[-114.662462095522,35.8709599070091],[-114.689867343369,35.8474424944766],[-114.682739704595,35.7647034175617],[-114.688820027649,35.7325957399896],[-114.665091345861,35.6930994107107],[-114.668486064922,35.6563989882404],[-114.654065925137,35.6465840800053],[-114.6398667219,35.6113485698329],[-114.653134321223,35.5848331056108],[-114.649792053474,35.5466373866597],[-114.672215155693,35.5157541647721],[-114.645396168451,35.4507608261463],[-114.589584275424,35.3583787306827],[-114.587889840369,35.30476812919],[-114.559583045727,35.2201828714608],[-114.561039964054,35.1743461616313],[-114.572255261053,35.1400677445931],[-114.582616239058,35.1325604694085],[-114.626440825485,35.1339067529872],[-114.6359090842,35.1186557767895],[-114.595631971944,35.0760579746697],[-114.633779872695,35.0418633504303],[-114.621068606189,34.9989144286133],[-115.626197382816,35.7956983148418],[-115.88576934392,36.0012259572723],[-117.160423771838,36.9595941441767],[-117.838686423167,37.457298239715],[-118.417419755966,37.8866767486211],[-119.152450421001,38.4118009590513]]], \"spatialReference\":{\"wkid\":4326}}";
-
- JsonFactory factory = new JsonFactory();
- JsonParser parser = factory.createJsonParser(strPolygon1);
- parser.nextToken();
- MapGeometry mapGeom = GeometryEngine.jsonToGeometry(parser);
- Geometry geom = mapGeom.getGeometry();
- OperatorExportToWkb operatorExport = (OperatorExportToWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkb);
- ByteBuffer byteBuffer = operatorExport.execute(0, geom, null);
- byte[] wkb = byteBuffer.array();
-
- // WKB -> GEOM -> JSON
- OperatorImportFromWkb operatorImport = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
- geom = operatorImport.execute(0, Geometry.Type.Polygon,
- ByteBuffer.wrap(wkb), null);
- // geom = operatorImport.execute(0, Geometry.Type.Polygon,
- // byteBuffer);
- String outputPolygon1 = GeometryEngine.geometryToJson(-1, geom);
- System.out.println(strPolygon1);
- System.out.println(outputPolygon1);
- } catch (JsonParseException ex) {
- } catch (IOException ex) {
- }
-
- }
-
- @Test
- public void testWKB2() throws Exception {
- // JSON -> GEOM -> WKB
-
- // String strPolygon1 =
- // "{\"xmin\":-1.16605115291E7,\"ymin\":4925189.941699997,\"xmax\":-1.16567772126E7,\"ymax\":4928658.771399997,\"spatialReference\":{\"wkid\":102100}}";
- String strPolygon1 = "{\"rings\" : [ [ [-1.16605115291E7,4925189.941699997], [-1.16567772126E7,4925189.941699997], [-1.16567772126E7,4928658.771399997], [-1.16605115291E7,4928658.771399997], [-1.16605115291E7,4925189.941699997] ] ], \"spatialReference\" : {\"wkid\" : 102100}}";
-
- JsonFactory factory = new JsonFactory();
- JsonParser parser = factory.createJsonParser(strPolygon1);
- parser.nextToken();
- MapGeometry mapGeom = GeometryEngine.jsonToGeometry(parser);
- Geometry geom = mapGeom.getGeometry();
-
- // simplifying geom
- OperatorSimplify operatorSimplify = (OperatorSimplify) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Simplify);
- SpatialReference sr = SpatialReference.create(102100);
- geom = operatorSimplify.execute(geom, sr, true, null);
-
- OperatorExportToWkb operatorExport = (OperatorExportToWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ExportToWkb);
- ByteBuffer byteBuffer = operatorExport.execute(0, geom, null);
- byte[] wkb = byteBuffer.array();
-
- // // checking WKB correctness
- // WKBReader jtsReader = new WKBReader();
- // com.vividsolutions.jts.geom.Geometry jtsGeom = jtsReader.read(wkb);
- // System.out.println("jtsGeom = " + jtsGeom);
-
- // WKB -> GEOM -> JSON
- OperatorImportFromWkb operatorImport = (OperatorImportFromWkb) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ImportFromWkb);
- geom = operatorImport.execute(0, Geometry.Type.Polygon,
- ByteBuffer.wrap(wkb), null);
- assertTrue(!geom.isEmpty());
- // geom = operatorImport.execute(0, Geometry.Type.Polygon, byteBuffer);
- // String outputPolygon1 = GeometryEngine.geometryToJson(-1, geom);
- // System.out.println(strPolygon1);
- // System.out.println(outputPolygon1);
-
- }
-
}
diff --git a/unittest/com/esri/core/geometry/TestWkid.java b/unittest/com/esri/core/geometry/TestWkid.java
deleted file mode 100644
index fc09a66c..00000000
--- a/unittest/com/esri/core/geometry/TestWkid.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.esri.core.geometry;
-
-import static org.junit.Assert.*;
-import junit.framework.TestCase;
-
-import org.junit.Test;
-
-public class TestWkid extends TestCase {
- @Test
- public void test() {
- SpatialReference sr = SpatialReference.create(102100);
- assertTrue(sr.getID() == 102100);
- assertTrue(sr.getLatestID() == 3857);
- assertTrue(sr.getOldID() == 102100);
- assertTrue(sr.getTolerance() == 0.001);
-
- SpatialReference sr84 = SpatialReference.create(4326);
- double tol84 = sr84.getTolerance();
- assertTrue(Math.abs(tol84 - 1e-8) < 1e-8 * 1e-8);
- }
-
-}