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/main/java/com/esri/core/geometry/EditShape.java b/src/main/java/com/esri/core/geometry/EditShape.java
index 84557893..ebbfb18d 100644
--- a/src/main/java/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,6 +25,8 @@
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
@@ -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;
}
@@ -585,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
@@ -699,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();
@@ -732,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);
}
@@ -821,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.
@@ -898,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;
@@ -1339,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);
}
@@ -1839,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);
@@ -2040,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;
@@ -2280,5 +2313,43 @@ boolean hasPointFeatures()
}
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/main/java/com/esri/core/geometry/Envelope.java b/src/main/java/com/esri/core/geometry/Envelope.java
index 0675a1e8..c254df1c 100644
--- a/src/main/java/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,15 +25,18 @@
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();
@@ -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();
}
/**
@@ -215,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();
@@ -244,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);
}
@@ -328,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);
@@ -341,7 +348,7 @@ void _setFromPoint(Point centerPoint) {
}
}
- void merge(Envelope2D other) {
+ public void merge(Envelope2D other) {
_touch();
m_envelope.merge(other);
}
@@ -415,7 +422,7 @@ public void copyTo(Geometry dst) {
{
envDst._ensureAttributes();
System.arraycopy(m_attributes, 0, envDst.m_attributes, 0,
- (m_description._getTotalComponents() - 2) * 2);
+ (m_description.getTotalComponentCount() - 2) * 2);
}
}
@@ -444,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);
@@ -493,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();
@@ -573,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);
}
@@ -601,7 +614,6 @@ int getEndPointOffset(VertexDescription descr, int end_point) {
throw new IllegalArgumentException();
int attribute_index = m_description.getAttributeIndex(semantics);
- _ensureAttributes();
if (attribute_index >= 0) {
return m_attributes[getEndPointOffset(m_description, end_point)
+ m_description.getPointAttributeOffset_(attribute_index)
@@ -636,7 +648,6 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
throw new IllegalArgumentException();
addAttribute(semantics);
- _ensureAttributes();
int attribute_index = m_description.getAttributeIndex(semantics);
m_attributes[getEndPointOffset(m_description, end_point)
+ m_description.getPointAttributeOffset_(attribute_index) - 2
@@ -645,37 +656,22 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
void _ensureAttributes() {
_touch();
- if (m_attributes == null && m_description._getTotalComponents() > 2) {
- m_attributes = new double[(m_description._getTotalComponents() - 2) * 2];
+ 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);
-
- int j = 0;
- for (int i = 1, n = m_description.getAttributeCount(); i < n; i++) {
- int semantics = m_description.getSemantics(i);
- int nords = VertexDescription.getComponentCount(semantics);
- double d = VertexDescription.getDefaultValue(semantics);
- for (int ord = 0; ord < nords; ord++)
- {
- m_attributes[offset0 + j] = d;
- m_attributes[offset1 + j] = d;
- j++;
- }
- }
+ System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset0, halfLength);
+ System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset1, halfLength);
}
}
@Override
protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
- if (m_attributes == null) {
- m_description = newDescription;
- return;
- }
-
- if (newDescription._getTotalComponents() > 2) {
+ if (newDescription.getTotalComponentCount() > 2) {
int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);
- double[] newAttributes = new double[(newDescription._getTotalComponents() - 2) * 2];
+ double[] newAttributes = new double[(newDescription.getTotalComponentCount() - 2) * 2];
int old_offset0 = _getEndPointOffset(m_description, 0);
int old_offset1 = _getEndPointOffset(m_description, 1);
@@ -725,8 +721,6 @@ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
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;
@@ -741,7 +735,6 @@ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
int attributeIndex = m_description.getAttributeIndex(semantics);
if (attributeIndex >= 0) {
- _ensureAttributes();
return m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex)
- 2 + ordinate];
@@ -775,14 +768,10 @@ 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);
- _ensureAttributes();
m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex) - 2
+ ordinate] = value;
@@ -793,10 +782,10 @@ int _getAttributeAsInt(int endPoint, int semantics, int ordinate) {
}
static int _getEndPointOffset(VertexDescription vd, int endPoint) {
- return endPoint * (vd._getTotalComponents() - 2);
+ return endPoint * (vd.getTotalComponentCount() - 2);
}
- boolean isIntersecting(Envelope2D other) {
+ public boolean isIntersecting(Envelope2D other) {
return m_envelope.isIntersecting(other);
}
@@ -875,7 +864,7 @@ public void normalize() {// TODO: attributes
*
* @return The center point of the envelope.
*/
- Point2D getCenter2D() {
+ public Point2D getCenter2D() {
return m_envelope.getCenter();
}
@@ -1005,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;
@@ -1021,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]);
}
}
@@ -1109,8 +1098,38 @@ public void setYMax(double y) {
m_envelope.ymax = y;
}
- @Override
- public Geometry getBoundary() {
- return Boundary.calculate(this, null);
- }
+ @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/main/java/com/esri/core/geometry/Envelope1D.java b/src/main/java/com/esri/core/geometry/Envelope1D.java
index 993eef36..e000ef0a 100644
--- a/src/main/java/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.
@@ -45,12 +45,20 @@ 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();
}
+ public void setCoords(Envelope1D other) {
+ setCoords(other.vmin, other.vmax);
+ }
+
public void normalize() {
if (NumberUtils.isNaN(vmin))
return;
@@ -71,7 +79,7 @@ public void setEmpty() {
}
public boolean isEmpty() {
- return NumberUtils.isNaN(vmin);
+ return NumberUtils.isNaN(vmin) || NumberUtils.isNaN(vmax);
}
public void setInfinite() {
@@ -125,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;
}
@@ -215,7 +225,13 @@ public boolean equals(Object _other)
@Override
public int hashCode() {
- return NumberUtils.hash(NumberUtils.hash(vmin), vmax);
+ if (isEmpty()) {
+ return NumberUtils.hash(NumberUtils.TheNaN);
+ }
+
+ int hash = NumberUtils.hash(vmin);
+ hash = NumberUtils.hash(hash, vmax);
+ return hash;
}
}
diff --git a/src/main/java/com/esri/core/geometry/Envelope2D.java b/src/main/java/com/esri/core/geometry/Envelope2D.java
index f2e4ef41..5c8bebf5 100644
--- a/src/main/java/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.
@@ -28,12 +28,14 @@
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 implements Serializable {
private static final long serialVersionUID = 1L;
-
+
private final static int XLESSXMIN = 1;
// private final int XGREATERXMAX = 2;
private final static int YLESSYMIN = 4;
@@ -59,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();
}
@@ -70,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;
@@ -114,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) {
@@ -144,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) {
@@ -181,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)
@@ -240,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
@@ -257,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.
*/
@@ -271,16 +292,39 @@ public boolean isIntersectingNE(Envelope2D other) {
// overlap
}
+ /**
+ * 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;
@@ -303,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) {
@@ -332,6 +381,7 @@ 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))
@@ -361,6 +411,7 @@ public void queryCorners(Point2D[] corners) {
* 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)))
@@ -462,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())
@@ -520,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);
@@ -583,6 +637,8 @@ public boolean contains(double x, double y) {
/**
* 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.
@@ -592,7 +648,10 @@ public boolean contains(Envelope2D other) {// Note: Will return False, if
/**
* Returns True if the envelope contains the point (boundary exclusive).
- */
+ * @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().
@@ -609,6 +668,8 @@ public boolean containsExclusive(Point2D pt) {
/**
* 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
@@ -638,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;
}
@@ -1037,8 +1089,10 @@ public boolean isPointOnBoundary(Point2D pt, double tolerance) {
/**
* 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(/* const */Envelope2D other)
+ public double distance(Envelope2D other)
{
return Math.sqrt(sqrDistance(other));
}
@@ -1046,6 +1100,8 @@ public double distance(/* const */Envelope2D other)
/**
* 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)
{
@@ -1055,6 +1111,8 @@ public double distance(Point2D pt2D)
/**
* 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)
{
@@ -1081,9 +1139,72 @@ public double sqrDistance(Envelope2D other)
return dx * dx + dy * dy;
}
+ /**
+ * 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)
{
diff --git a/src/main/java/com/esri/core/geometry/Envelope2DIntersectorImpl.java b/src/main/java/com/esri/core/geometry/Envelope2DIntersectorImpl.java
index 5fdb9fc3..35b83daa 100644
--- a/src/main/java/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.
@@ -99,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)
@@ -141,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)
@@ -254,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.
*/
@@ -278,7 +290,6 @@ int getRedElement(int handle_a) {
/*
* Returns the user element associated with handle_b.
*/
-
int getBlueElement(int handle_b) {
return m_elements_blue.read(handle_b);
}
@@ -310,8 +321,7 @@ int getBlueElement(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;
@@ -344,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);
@@ -361,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();
@@ -383,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);
@@ -400,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) {
@@ -427,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);
@@ -444,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) {
@@ -471,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());
@@ -506,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();
@@ -532,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)) {
@@ -549,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;
@@ -574,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;
@@ -591,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);
@@ -612,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);
@@ -640,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);
@@ -654,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 {
@@ -670,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;
}
@@ -679,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);
@@ -702,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);
@@ -716,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 {
@@ -733,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;
}
@@ -761,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;
@@ -774,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;
@@ -885,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));
}
@@ -904,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;
@@ -938,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/main/java/com/esri/core/geometry/Envelope3D.java b/src/main/java/com/esri/core/geometry/Envelope3D.java
index 1dd38ef6..6fa8b522 100644
--- a/src/main/java/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.
@@ -47,20 +47,23 @@ public final class Envelope3D implements Serializable{
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();
@@ -72,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() {
@@ -99,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) {
@@ -118,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) {
@@ -129,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;
@@ -189,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/main/java/com/esri/core/geometry/GeoDist.java b/src/main/java/com/esri/core/geometry/GeoDist.java
index 9a1b410d..b7845151 100644
--- a/src/main/java/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
index 04da23ce..6290a0f6 100644
--- a/src/main/java/com/esri/core/geometry/GeoJsonExportFlags.java
+++ b/src/main/java/com/esri/core/geometry/GeoJsonExportFlags.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,31 @@
package com.esri.core.geometry;
public interface GeoJsonExportFlags {
- static final int geoJsonExportDefaults = 0;
- static final int geoJsonExportPreferMultiGeometry = 1;
+ 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
index e2539151..5245bd96 100644
--- a/src/main/java/com/esri/core/geometry/GeoJsonImportFlags.java
+++ b/src/main/java/com/esri/core/geometry/GeoJsonImportFlags.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,15 @@
package com.esri.core.geometry;
public interface GeoJsonImportFlags {
- static final int geoJsonImportDefaults = 0;
- static final int geoJsonImportNonTrusted = 2;
+ 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/main/java/com/esri/core/geometry/GeodeticCurveType.java b/src/main/java/com/esri/core/geometry/GeodeticCurveType.java
index b07a73e1..3dc053af 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/Geometry.java b/src/main/java/com/esri/core/geometry/Geometry.java
index d4cd9952..d108d328 100644
--- a/src/main/java/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,20 +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;
@@ -50,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
@@ -59,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;
}
@@ -118,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();
+ }
}
/**
@@ -144,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;
@@ -153,8 +177,9 @@ 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;
@@ -162,14 +187,15 @@ void assignVertexDescription(VertexDescription src) {
_assignVertexDescriptionImpl(src);
}
- protected abstract void _assignVertexDescriptionImpl(VertexDescription 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;
@@ -184,6 +210,8 @@ void mergeVertexDescription(VertexDescription src) {
/**
* 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);
@@ -192,7 +220,7 @@ 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();
@@ -208,6 +236,7 @@ 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();
@@ -227,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);
@@ -239,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);
@@ -259,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);
@@ -268,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);
@@ -305,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.
*/
@@ -421,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;
@@ -502,14 +537,24 @@ 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 endpoints. For Multi_point
- * and Point NULL is returned.
- */
- public abstract Geometry getBoundary();
+ /**
+ * 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();
@@ -559,7 +604,27 @@ static public enum GeometryAccelerationDegree {
}
Object writeReplace() throws ObjectStreamException {
- GeometrySerializer geomSerializer = new GeometrySerializer();
+ Type gt = getType();
+ if (gt == Geometry.Type.Point)
+ {
+ PtSrlzr pt = new PtSrlzr();
+ pt.setGeometryByValue((Point)this);
+ return pt;
+ }
+ else if (gt == Geometry.Type.Envelope)
+ {
+ EnvSrlzr e = new EnvSrlzr();
+ e.setGeometryByValue((Envelope)this);
+ return e;
+ }
+ else if (gt == Geometry.Type.Line)
+ {
+ LnSrlzr ln = new LnSrlzr();
+ ln.setGeometryByValue((Line)this);
+ return ln;
+ }
+
+ GenericGeometrySerializer geomSerializer = new GenericGeometrySerializer();
geomSerializer.setGeometryByValue(this);
return geomSerializer;
}
@@ -578,4 +643,31 @@ public String toString() {
}
}
+ /**
+ * 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
index 18140ee3..90d699d0 100644
--- a/src/main/java/com/esri/core/geometry/GeometryAccelerators.java
+++ b/src/main/java/com/esri/core/geometry/GeometryAccelerators.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,13 +23,11 @@
*/
package com.esri.core.geometry;
-import java.util.ArrayList;
-
class GeometryAccelerators {
private RasterizedGeometry2D m_rasterizedGeometry;
private QuadTreeImpl m_quad_tree;
- private ArrayList m_path_envelopes;
+ private QuadTreeImpl m_quad_tree_for_paths;
public RasterizedGeometry2D getRasterizedGeometry() {
return m_rasterizedGeometry;
@@ -39,8 +37,8 @@ public QuadTreeImpl getQuadTree() {
return m_quad_tree;
}
- public ArrayList getPathEnvelopes() {
- return m_path_envelopes;
+ public QuadTreeImpl getQuadTreeForPaths() {
+ return m_quad_tree_for_paths;
}
void _setRasterizedGeometry(RasterizedGeometry2D rg) {
@@ -51,9 +49,7 @@ void _setQuadTree(QuadTreeImpl quad_tree) {
m_quad_tree = quad_tree;
}
- void _setPathEnvelopes(ArrayList pe) {
- m_path_envelopes = pe;
- }
+ void _setQuadTreeForPaths(QuadTreeImpl quad_tree) { m_quad_tree_for_paths = quad_tree; }
static boolean canUseRasterizedGeometry(Geometry geom) {
if (geom.isEmpty()
@@ -77,12 +73,20 @@ static boolean canUseQuadTree(Geometry geom) {
return true;
}
- static boolean canUsePathEnvelopes(Geometry geom) {
- if (geom.isEmpty()
- || !(geom.getType() == Geometry.Type.Polyline || geom.getType() == Geometry.Type.Polygon)) {
- return false;
- }
+ static boolean canUseQuadTreeForPaths(Geometry geom) {
+ if (geom.isEmpty() || !(geom.getType() == Geometry.Type.Polyline || geom.getType() == Geometry.Type.Polygon))
+ return false;
- return true;
+ 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/main/java/com/esri/core/geometry/GeometryCursor.java b/src/main/java/com/esri/core/geometry/GeometryCursor.java
index 503dfe4c..3c2ef5d6 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/GeometryCursorAppend.java b/src/main/java/com/esri/core/geometry/GeometryCursorAppend.java
index cbf3faee..dec0b708 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/GeometryEngine.java b/src/main/java/com/esri/core/geometry/GeometryEngine.java
index 048994dd..99466fd2 100644
--- a/src/main/java/com/esri/core/geometry/GeometryEngine.java
+++ b/src/main/java/com/esri/core/geometry/GeometryEngine.java
@@ -1,898 +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.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.json.JSONException;
-
-/**
- * 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, 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.
- * @throws IOException
- * @throws JsonParseException
- */
- public static MapGeometry jsonToGeometry(String json) throws JsonParseException, IOException {
- 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);
- }
-
- /**
- * 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 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.
- *
- * See OperatorImportFromGeoJson.
- *
- * @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.
- *
- * 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);
- }
-}
+/*
+ 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/main/java/com/esri/core/geometry/GeometryException.java b/src/main/java/com/esri/core/geometry/GeometryException.java
index 07b11ffd..97638685 100644
--- a/src/main/java/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,8 @@ public class GeometryException extends RuntimeException {
* @param str
* - The error string.
*/
- GeometryException(String str) {
- super(str);
- internalCode = 0;
- }
-
- GeometryException(String str, int sgCode) {
+ public GeometryException(String str) {
super(str);
- internalCode = sgCode;
}
static GeometryException GeometryInternalError() {
diff --git a/src/main/java/com/esri/core/geometry/GeometrySerializer.java b/src/main/java/com/esri/core/geometry/GeometrySerializer.java
index 8bf9f401..a2fefa1e 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/IndexHashTable.java b/src/main/java/com/esri/core/geometry/IndexHashTable.java
index 4e60b59e..b0117bb8 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/IndexMultiDCList.java b/src/main/java/com/esri/core/geometry/IndexMultiDCList.java
index b7a0a119..c20adbec 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/IndexMultiList.java b/src/main/java/com/esri/core/geometry/IndexMultiList.java
index 44b1da78..b008094a 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/InternalUtils.java b/src/main/java/com/esri/core/geometry/InternalUtils.java
index 90c84f48..257eb63f 100644
--- a/src/main/java/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
@@ -243,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();
@@ -306,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);
@@ -431,115 +474,94 @@ static Envelope2DIntersectorImpl getEnvelope2DIntersector(
return intersector;
}
- 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();
+ 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);
-
- GeometryAccelerators accel_a = multipathImplA._getAccelerators();
- ArrayList path_envelopes_a = null;
-
- if (accel_a != null) {
- path_envelopes_a = accel_a.getPathEnvelopes();
- }
+ 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 (bExteriorOnlyA && 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;
- if (path_envelopes_a != null) {
- Envelope2D env = path_envelopes_a.get(ipath_a);
+ multipathImplA.queryPathEnvelope2D(ipath_a, env_a);
- if (!env.isIntersecting(envInter)) {
- continue;
- }
+ if (!env_a.isIntersecting(envInter))
+ continue;
- b_found_red = true;
- intersector.addRedEnvelope(ipath_a, env);
- } else {
- multipathImplA.queryPathEnvelope2D(ipath_a, env_a);
+ b_found_red = true;
+ intersector.addRedEnvelope(ipath_a, env_a);
+ }
+ intersector.endRedConstruction();
- if (!env_a.isIntersecting(envInter)) {
- continue;
- }
+ if (!b_found_red)
+ return null;
- b_found_red = true;
- Envelope2D env = new Envelope2D();
- env.setCoords(env_a);
- intersector.addRedEnvelope(ipath_a, env);
- }
- }
- intersector.endRedConstruction();
+ 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;
- if (!b_found_red) {
- return null;
- }
+ multipathImplB.queryPathEnvelope2D(ipath_b, env_b);
- GeometryAccelerators accel_b = multipathImplB._getAccelerators();
- ArrayList path_envelopes_b = null;
+ if (!env_b.isIntersecting(envInter))
+ continue;
- if (accel_b != null) {
- path_envelopes_b = accel_b.getPathEnvelopes();
- }
+ b_found_blue = true;
+ intersector.addBlueEnvelope(ipath_b, env_b);
+ }
+ intersector.endBlueConstruction();
- boolean b_found_blue = false;
- intersector.startBlueConstruction();
- for (int ipath_b = 0; ipath_b < multipathImplB.getPathCount(); ipath_b++) {
- if (bExteriorOnlyB && type_b == Geometry.GeometryType.Polygon
- && !multipathImplB.isExteriorRing(ipath_b)) {
- continue;
- }
+ if (!b_found_blue)
+ return null;
- if (path_envelopes_b != null) {
- Envelope2D env = path_envelopes_b.get(ipath_b);
+ return intersector;
+ }
- if (!env.isIntersecting(envInter)) {
- continue;
- }
+ 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();
- b_found_blue = true;
- intersector.addBlueEnvelope(ipath_b, env);
- } else {
- multipathImplB.queryPathEnvelope2D(ipath_b, env_b);
+ 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 (!env_b.isIntersecting(envInter)) {
- continue;
+ if (hint_index == -1) {
+ throw new GeometryException("internal error");
}
-
- b_found_blue = true;
- Envelope2D env = new Envelope2D();
- env.setCoords(env_b);
- intersector.addBlueEnvelope(ipath_b, env);
}
}
- intersector.endBlueConstruction();
- if (!b_found_blue) {
- return null;
- }
-
- return intersector;
- }
-
- static boolean isWeakSimple(MultiVertexGeometry geom, double tol) {
- return ((MultiVertexGeometryImpl) geom._getImpl()).getIsSimple(tol) > 0;
+ return quad_tree;
}
+
}
+
diff --git a/src/main/java/com/esri/core/geometry/Interop.java b/src/main/java/com/esri/core/geometry/Interop.java
index 38df1b52..b47801c7 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/IntervalTreeImpl.java b/src/main/java/com/esri/core/geometry/IntervalTreeImpl.java
index 1237e798..f7248c47 100644
--- a/src/main/java/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 GeometryException.GeometryInternalError();
- }
- }
+ 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/main/java/com/esri/core/geometry/JSONArrayEnumerator.java b/src/main/java/com/esri/core/geometry/JSONArrayEnumerator.java
deleted file mode 100644
index 5b2d93d7..00000000
--- a/src/main/java/com/esri/core/geometry/JSONArrayEnumerator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- 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.util.ArrayList;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-final class JSONArrayEnumerator {
-
- private JSONArray m_jsonArray;
- private boolean m_bStarted;
- private int m_currentIndex;
-
- JSONArrayEnumerator(JSONArray jsonArray) {
- m_bStarted = false;
- m_currentIndex = -1;
- m_jsonArray = jsonArray;
- }
-
- Object getCurrentObject() {
- if (!m_bStarted) {
- throw new GeometryException("invalid call");
- }
-
- if (m_currentIndex == m_jsonArray.length()) {
- throw new GeometryException("invalid call");
- }
-
- return m_jsonArray.opt(m_currentIndex);
- }
-
- boolean next() {
- if (!m_bStarted) {
- m_currentIndex = 0;
- m_bStarted = true;
- } else if (m_currentIndex != m_jsonArray.length()) {
- m_currentIndex++;
- }
-
- return m_currentIndex != m_jsonArray.length();
- }
-}
-
diff --git a/src/main/java/com/esri/core/geometry/JSONObjectEnumerator.java b/src/main/java/com/esri/core/geometry/JSONObjectEnumerator.java
deleted file mode 100644
index f474a16c..00000000
--- a/src/main/java/com/esri/core/geometry/JSONObjectEnumerator.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- 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.util.ArrayList;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-final class JSONObjectEnumerator {
-
- private JSONObject m_jsonObject;
- private boolean m_bStarted;
- private int m_currentIndex;
- private String[] m_keys;
-
- JSONObjectEnumerator(JSONObject jsonObject) {
- m_bStarted = false;
- m_currentIndex = -1;
- m_jsonObject = jsonObject;
- }
-
- String getCurrentKey() {
- if (!m_bStarted) {
- throw new GeometryException("invalid call");
- }
-
- if (m_currentIndex == m_jsonObject.length()) {
- throw new GeometryException("invalid call");
- }
-
- return m_keys[m_currentIndex];
- }
-
- Object getCurrentObject() {
- if (!m_bStarted) {
- throw new GeometryException("invalid call");
- }
-
- if (m_currentIndex == m_jsonObject.length()) {
- throw new GeometryException("invalid call");
- }
-
- return m_jsonObject.opt(m_keys[m_currentIndex]);
- }
-
- boolean next() {
- if (!m_bStarted) {
- m_currentIndex = 0;
- m_keys = JSONObject.getNames(m_jsonObject);
- m_bStarted = true;
- } else if (m_currentIndex != m_jsonObject.length()) {
- m_currentIndex++;
- }
-
- return m_currentIndex != m_jsonObject.length();
- }
-}
diff --git a/src/main/java/com/esri/core/geometry/JSONUtils.java b/src/main/java/com/esri/core/geometry/JSONUtils.java
index 1ec51185..14bcf142 100644
--- a/src/main/java/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,26 +23,21 @@
*/
package com.esri.core.geometry;
-import java.io.IOException;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonToken;
-
final class JSONUtils {
static boolean isObjectStart(JsonReader parser) throws Exception {
- return parser.currentToken() == null ? parser.nextToken() == JsonToken.START_OBJECT
- : parser.currentToken() == JsonToken.START_OBJECT;
+ return parser.currentToken() == null ? parser.nextToken() == JsonReader.Token.START_OBJECT
+ : parser.currentToken() == JsonReader.Token.START_OBJECT;
}
- static double readDouble(JsonReader parser) throws JsonParseException,
- IOException, Exception {
- if (parser.currentToken() == JsonToken.VALUE_NUMBER_FLOAT)
+ static double readDouble(JsonReader parser) {
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_FLOAT)
return parser.currentDoubleValue();
- else if (parser.currentToken() == JsonToken.VALUE_NUMBER_INT)
+ else if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
return parser.currentIntValue();
- else if (parser.currentToken() == JsonToken.VALUE_NULL)
+ else if (parser.currentToken() == JsonReader.Token.VALUE_NULL)
return NumberUtils.NaN();
- else if (parser.currentToken() == JsonToken.VALUE_STRING)
+ else if (parser.currentToken() == JsonReader.Token.VALUE_STRING)
if (parser.currentString().equals("NaN"))
return NumberUtils.NaN();
diff --git a/src/main/java/com/esri/core/geometry/JsonCursor.java b/src/main/java/com/esri/core/geometry/JsonCursor.java
index 30e1beed..0af0024f 100644
--- a/src/main/java/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.
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
index efa6f55d..90427c63 100644
--- a/src/main/java/com/esri/core/geometry/JsonParserReader.java
+++ b/src/main/java/com/esri/core/geometry/JsonParserReader.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,51 +21,151 @@
email: contracts@esri.com
*/
+
package com.esri.core.geometry;
-import java.util.ArrayList;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.json.JSONArray;
-import org.json.JSONObject;
+import com.fasterxml.jackson.core.*;
-final class JsonParserReader extends JsonReader {
+/**
+ * A throw in JsonReader built around the Jackson JsonParser.
+ *
+ */
+public class JsonParserReader implements JsonReader {
private JsonParser m_jsonParser;
- JsonParserReader(JsonParser 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
- JsonToken nextToken() throws Exception {
- JsonToken token = m_jsonParser.nextToken();
- return token;
+ public Token nextToken() throws JsonGeometryException {
+ try {
+ JsonToken token = m_jsonParser.nextToken();
+ return mapToken(token);
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
}
@Override
- JsonToken currentToken() throws Exception {
- return m_jsonParser.getCurrentToken();
+ public Token currentToken() throws JsonGeometryException {
+ try {
+ return mapToken(m_jsonParser.getCurrentToken());
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
}
@Override
- void skipChildren() throws Exception {
- m_jsonParser.skipChildren();
+ public void skipChildren() throws JsonGeometryException {
+ try {
+ m_jsonParser.skipChildren();
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+
}
@Override
- String currentString() throws Exception {
- return m_jsonParser.getText();
+ public String currentString() throws JsonGeometryException {
+ try {
+ return m_jsonParser.getText();
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+
}
@Override
- double currentDoubleValue() throws Exception {
- return m_jsonParser.getValueAsDouble();
+ public double currentDoubleValue() throws JsonGeometryException {
+ try {
+ return m_jsonParser.getValueAsDouble();
+ } catch (Exception ex) {
+ throw new JsonGeometryException(ex);
+ }
+
}
@Override
- int currentIntValue() throws Exception {
- return m_jsonParser.getValueAsInt();
+ 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
index 1b3a4f03..541143e3 100644
--- a/src/main/java/com/esri/core/geometry/JsonReader.java
+++ b/src/main/java/com/esri/core/geometry/JsonReader.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,25 +23,38 @@
*/
package com.esri.core.geometry;
-import java.util.ArrayList;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-
-abstract class JsonReader {
-
- abstract JsonToken nextToken() throws Exception;
-
- abstract JsonToken currentToken() throws Exception;
-
- abstract void skipChildren() throws Exception;
-
- abstract String currentString() throws Exception;
-
- abstract double currentDoubleValue() throws Exception;
-
- abstract int currentIntValue() throws Exception;
+/**
+ * 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/main/java/com/esri/core/geometry/JsonParserCursor.java b/src/main/java/com/esri/core/geometry/JsonReaderCursor.java
similarity index 83%
rename from src/main/java/com/esri/core/geometry/JsonParserCursor.java
rename to src/main/java/com/esri/core/geometry/JsonReaderCursor.java
index fe3605ab..8e0f16de 100644
--- a/src/main/java/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
index 135b8463..a8df0930 100644
--- a/src/main/java/com/esri/core/geometry/JsonStringWriter.java
+++ b/src/main/java/com/esri/core/geometry/JsonStringWriter.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,374 +25,402 @@
final class JsonStringWriter extends JsonWriter {
- @Override
- Object getJson() {
- next_(Action.accept);
- return m_jsonString.toString();
- }
-
- @Override
- void startObject() {
- next_(Action.addContainer);
- m_jsonString.append('{');
- m_functionStack.add(State.objectStart);
- }
-
- @Override
- void startArray() {
- next_(Action.addContainer);
- 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 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 addPairDoubleF(String fieldName, double v, int decimals) {
- next_(Action.addPair);
- appendQuote_(fieldName);
- m_jsonString.append(":");
- addValueDoubleF_(v, decimals);
- }
-
- @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.addValue);
- addValueObject_();
- }
-
- @Override
- void addValueArray() {
- next_(Action.addValue);
- addValueArray_();
- }
-
- @Override
- void addValueString(String v) {
- next_(Action.addValue);
- addValueString_(v);
- }
-
- @Override
- void addValueDouble(double v) {
- next_(Action.addValue);
- addValueDouble_(v);
- }
-
- @Override
- void addValueDoubleF(double v, int decimals) {
- next_(Action.addValue);
- addValueDoubleF_(v, decimals);
- }
-
- @Override
- void addValueInt(int v) {
- next_(Action.addValue);
- addValueInt_(v);
- }
-
- @Override
- void addValueBoolean(boolean v) {
- next_(Action.addValue);
- addValueBoolean_(v);
- }
-
- @Override
- void addValueNull() {
- next_(Action.addValue);
- 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 addValueDoubleF_(double v, int decimals) {
- if (NumberUtils.isNaN(v)) {
- addValueNull_();
- return;
- }
-
- StringUtils.appendDoubleF(v, decimals, 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;
- default:
- throw GeometryException.GeometryInternalError();
- }
- }
-
- private void accept_(int action) {
- if (action != Action.accept) {
- throw new GeometryException("invalid call");
- }
- }
-
- private void start_(int action) {
- if (action == Action.addContainer) {
- m_functionStack.removeLast();
- } else {
- throw new GeometryException("invalid call");
- }
- }
-
- private void objectStart_(int action) {
- m_functionStack.removeLast();
-
- if (action == Action.addPair) {
- m_functionStack.add(State.pairEnd);
- } else if (action != Action.popObject) {
- throw new GeometryException("invalid call");
- }
- }
-
- private void pairEnd_(int action) {
- if (action == Action.addPair) {
- m_jsonString.append(',');
- } else if (action == Action.popObject) {
- m_functionStack.removeLast();
- } else {
- throw new GeometryException("invalid call");
- }
- }
-
- private void arrayStart_(int action) {
- m_functionStack.removeLast();
-
- if (action == Action.addValue) {
- m_functionStack.add(State.elementEnd);
- } else if (action != Action.popArray) {
- throw new GeometryException("invalid call");
- }
- }
-
- private void elementEnd_(int action) {
- if (action == Action.addValue) {
- m_jsonString.append(',');
- } else if (action == Action.popArray) {
- m_functionStack.removeLast();
- } else {
- throw new GeometryException("invalid call");
- }
- }
-
- 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('"');
- }
+ @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/JsonValueReader.java b/src/main/java/com/esri/core/geometry/JsonValueReader.java
deleted file mode 100644
index 9f320029..00000000
--- a/src/main/java/com/esri/core/geometry/JsonValueReader.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- 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.util.ArrayList;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-
-final class JsonValueReader extends JsonReader {
-
- private Object m_object;
- private JsonToken m_currentToken;
- private ArrayList m_parentStack;
- private ArrayList m_objIters;
- private ArrayList m_arrIters;
-
- JsonValueReader(Object object) {
- m_object = object;
-
- boolean bJSONObject = (m_object instanceof JSONObject);
- boolean bJSONArray = (m_object instanceof JSONArray);
-
- if (!bJSONObject && !bJSONArray) {
- throw new IllegalArgumentException();
- }
-
- m_parentStack = new ArrayList(0);
- m_objIters = new ArrayList(0);
- m_arrIters = new ArrayList(0);
-
- m_parentStack.ensureCapacity(4);
- m_objIters.ensureCapacity(4);
- m_arrIters.ensureCapacity(4);
-
- if (bJSONObject) {
- JSONObjectEnumerator objIter = new JSONObjectEnumerator((JSONObject) m_object);
- m_parentStack.add(JsonToken.START_OBJECT);
- m_objIters.add(objIter);
- m_currentToken = JsonToken.START_OBJECT;
- } else {
- JSONArrayEnumerator arrIter = new JSONArrayEnumerator((JSONArray) m_object);
- m_parentStack.add(JsonToken.START_ARRAY);
- m_arrIters.add(arrIter);
- m_currentToken = JsonToken.START_ARRAY;
- }
- }
-
- private void setCurrentToken_(Object obj) {
- if (obj instanceof String) {
- m_currentToken = JsonToken.VALUE_STRING;
- } else if (obj instanceof Double || obj instanceof Float) {
- m_currentToken = JsonToken.VALUE_NUMBER_FLOAT;
- } else if (obj instanceof Integer || obj instanceof Long || obj instanceof Short) {
- m_currentToken = JsonToken.VALUE_NUMBER_INT;
- } else if (obj instanceof Boolean) {
- Boolean bObj = (Boolean) obj;
- boolean b = bObj.booleanValue();
- if (b) {
- m_currentToken = JsonToken.VALUE_TRUE;
- } else {
- m_currentToken = JsonToken.VALUE_FALSE;
- }
- } else if (obj instanceof JSONObject) {
- m_currentToken = JsonToken.START_OBJECT;
- } else if (obj instanceof JSONArray) {
- m_currentToken = JsonToken.START_ARRAY;
- } else {
- m_currentToken = JsonToken.VALUE_NULL;
- }
- }
-
- Object currentObject_() {
- assert (!m_parentStack.isEmpty());
-
- JsonToken parentType = m_parentStack.get(m_parentStack.size() - 1);
-
- if (parentType == JsonToken.START_OBJECT) {
- JSONObjectEnumerator objIter = m_objIters.get(m_objIters.size() - 1);
- return objIter.getCurrentObject();
- }
-
- JSONArrayEnumerator arrIter = m_arrIters.get(m_arrIters.size() - 1);
- return arrIter.getCurrentObject();
- }
-
- @Override
- JsonToken nextToken() throws Exception {
- if (m_parentStack.isEmpty()) {
- m_currentToken = JsonToken.NOT_AVAILABLE;
- return m_currentToken;
- }
-
- JsonToken parentType = m_parentStack.get(m_parentStack.size() - 1);
-
- if (parentType == JsonToken.START_OBJECT) {
- JSONObjectEnumerator iterator = m_objIters.get(m_objIters.size() - 1);
-
- if (m_currentToken == JsonToken.FIELD_NAME) {
- Object nextJSONValue = iterator.getCurrentObject();
-
- if (nextJSONValue instanceof JSONObject) {
- m_parentStack.add(JsonToken.START_OBJECT);
- m_objIters.add(new JSONObjectEnumerator((JSONObject) nextJSONValue));
- m_currentToken = JsonToken.START_OBJECT;
- } else if (nextJSONValue instanceof JSONArray) {
- m_parentStack.add(JsonToken.START_ARRAY);
- m_arrIters.add(new JSONArrayEnumerator((JSONArray) nextJSONValue));
- m_currentToken = JsonToken.START_ARRAY;
- } else {
- setCurrentToken_(nextJSONValue);
- }
- } else {
- if (iterator.next()) {
- m_currentToken = JsonToken.FIELD_NAME;
- } else {
- m_objIters.remove(m_objIters.size() - 1);
- m_parentStack.remove(m_parentStack.size() - 1);
- m_currentToken = JsonToken.END_OBJECT;
- }
- }
- } else {
- assert (parentType == JsonToken.START_ARRAY);
- JSONArrayEnumerator iterator = m_arrIters.get(m_arrIters.size() - 1);
- if (iterator.next()) {
- Object nextJSONValue = iterator.getCurrentObject();
-
- if (nextJSONValue instanceof JSONObject) {
- m_parentStack.add(JsonToken.START_OBJECT);
- m_objIters.add(new JSONObjectEnumerator((JSONObject) nextJSONValue));
- m_currentToken = JsonToken.START_OBJECT;
- } else if (nextJSONValue instanceof JSONArray) {
- m_parentStack.add(JsonToken.START_ARRAY);
- m_arrIters.add(new JSONArrayEnumerator((JSONArray) nextJSONValue));
- m_currentToken = JsonToken.START_ARRAY;
- } else {
- setCurrentToken_(nextJSONValue);
- }
- } else {
- m_arrIters.remove(m_arrIters.size() - 1);
- m_parentStack.remove(m_parentStack.size() - 1);
- m_currentToken = JsonToken.END_ARRAY;
- }
- }
-
- return m_currentToken;
- }
-
- @Override
- JsonToken currentToken() throws Exception {
- return m_currentToken;
- }
-
- @Override
- void skipChildren() throws Exception {
- assert (!m_parentStack.isEmpty());
-
- if (m_currentToken != JsonToken.START_OBJECT && m_currentToken != JsonToken.START_ARRAY) {
- return;
- }
-
- JsonToken parentType = m_parentStack.get(m_parentStack.size() - 1);
-
- if (parentType == JsonToken.START_OBJECT) {
- m_objIters.remove(m_objIters.size() - 1);
- m_parentStack.remove(m_parentStack.size() - 1);
- m_currentToken = JsonToken.END_OBJECT;
- } else {
- m_arrIters.remove(m_arrIters.size() - 1);
- m_parentStack.remove(m_parentStack.size() - 1);
- m_currentToken = JsonToken.END_ARRAY;
- }
- }
-
- @Override
- String currentString() throws Exception {
- if (m_currentToken == JsonToken.FIELD_NAME) {
- return m_objIters.get(m_objIters.size() - 1).getCurrentKey();
- }
-
- if (m_currentToken != JsonToken.VALUE_STRING) {
- throw new GeometryException("invalid call");
- }
-
- return ((String) currentObject_()).toString();
- }
-
- @Override
- double currentDoubleValue() throws Exception {
- if (m_currentToken != JsonToken.VALUE_NUMBER_FLOAT && m_currentToken != JsonToken.VALUE_NUMBER_INT) {
- throw new GeometryException("invalid call");
- }
-
- return ((Number) currentObject_()).doubleValue();
- }
-
- @Override
- int currentIntValue() throws Exception {
- if (m_currentToken != JsonToken.VALUE_NUMBER_INT) {
- throw new GeometryException("invalid call");
- }
-
- return ((Number) currentObject_()).intValue();
- }
-}
diff --git a/src/main/java/com/esri/core/geometry/JsonWriter.java b/src/main/java/com/esri/core/geometry/JsonWriter.java
index 28e15874..095f50e1 100644
--- a/src/main/java/com/esri/core/geometry/JsonWriter.java
+++ b/src/main/java/com/esri/core/geometry/JsonWriter.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,66 +25,72 @@
abstract class JsonWriter {
- abstract Object getJson();
+ abstract Object getJson();
- abstract void startObject();
+ abstract void startObject();
- abstract void startArray();
+ abstract void startArray();
- abstract void endObject();
+ abstract void endObject();
- abstract void endArray();
+ abstract void endArray();
- abstract void addPairObject(String fieldName);
+ abstract void addFieldName(String fieldName);
- abstract void addPairArray(String fieldName);
+ abstract void addPairObject(String fieldName);
- abstract void addPairString(String fieldName, String v);
+ abstract void addPairArray(String fieldName);
- abstract void addPairDouble(String fieldName, double v);
+ abstract void addPairString(String fieldName, String v);
- abstract void addPairDoubleF(String fieldName, double v, int decimals);
+ abstract void addPairDouble(String fieldName, double v);
- abstract void addPairInt(String fieldName, int v);
+ abstract void addPairDouble(String fieldName, double v, int precision, boolean bFixedPoint);
- abstract void addPairBoolean(String fieldName, boolean v);
+ abstract void addPairInt(String fieldName, int v);
- abstract void addPairNull(String fieldName);
+ abstract void addPairBoolean(String fieldName, boolean v);
- abstract void addValueObject();
+ abstract void addPairNull(String fieldName);
- abstract void addValueArray();
+ abstract void addValueObject();
- abstract void addValueString(String v);
+ abstract void addValueArray();
- abstract void addValueDouble(double v);
+ abstract void addValueString(String v);
- abstract void addValueDoubleF(double v, int decimals);
+ abstract void addValueDouble(double v);
- abstract void addValueInt(int v);
+ abstract void addValueDouble(double v, int precision, boolean bFixedPoint);
- abstract void addValueBoolean(boolean v);
+ abstract void addValueInt(int v);
- abstract void addValueNull();
+ abstract void addValueBoolean(boolean v);
- protected interface Action {
+ abstract void addValueNull();
- static final int accept = 0;
- static final int addContainer = 1;
- static final int popObject = 4;
- static final int popArray = 8;
- static final int addPair = 16;
- static final int addValue = 32;
- }
+ protected interface Action {
- protected interface State {
+ 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;
+ }
- 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 = 6;
- }
-}
+ 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/main/java/com/esri/core/geometry/Line.java b/src/main/java/com/esri/core/geometry/Line.java
index 881cdcef..ce7b7b23 100644
--- a/src/main/java/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.
@@ -29,24 +29,25 @@
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;
@@ -95,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);
@@ -190,56 +191,29 @@ public Geometry createInstance() {
}
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();
@@ -289,7 +263,7 @@ 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");
@@ -300,7 +274,7 @@ public double getAttributeAsDbl(double t, int semantics, int ordinate) {
}
@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;
@@ -420,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);
}
@@ -574,6 +548,11 @@ public boolean equals(Object other) {
return _equalsImpl((Segment)other);
}
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
boolean equals(Line other) {
if (other == this)
return true;
@@ -1002,6 +981,25 @@ 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) {
@@ -1014,4 +1012,13 @@ void _copyToImpl(Segment dst) {
}
+ /**
+ * 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/main/java/com/esri/core/geometry/ListeningGeometryCursor.java b/src/main/java/com/esri/core/geometry/ListeningGeometryCursor.java
index 04de301e..965a6798 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/MapGeometry.java b/src/main/java/com/esri/core/geometry/MapGeometry.java
index e28cd631..dbd90646 100644
--- a/src/main/java/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;
@@ -132,6 +134,22 @@ public boolean equals(Object other) {
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();
diff --git a/src/main/java/com/esri/core/geometry/MapGeometryCursor.java b/src/main/java/com/esri/core/geometry/MapGeometryCursor.java
index 81b0b195..b7cec8e4 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/MapOGCStructure.java b/src/main/java/com/esri/core/geometry/MapOGCStructure.java
index 61ec600e..c4eb5241 100644
--- a/src/main/java/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
index f6c9311a..92d5d8dd 100644
--- a/src/main/java/com/esri/core/geometry/MathUtils.java
+++ b/src/main/java/com/esri/core/geometry/MathUtils.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 MathUtils {
+final class MathUtils {
/**
* The implementation of the Kahan summation algorithm. Use to get better
* precision when adding a lot of values.
@@ -135,11 +135,21 @@ 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 - Math.floor(x / y) * y;
+ return x - truncate(x / y) * y;
}
@@ -154,4 +164,75 @@ static double round(double v) {
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/main/java/com/esri/core/geometry/MgrsConversionMode.java b/src/main/java/com/esri/core/geometry/MgrsConversionMode.java
deleted file mode 100644
index 21b54da8..00000000
--- a/src/main/java/com/esri/core/geometry/MgrsConversionMode.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- 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;
-
-/**
- * The modes for converting between military grid reference system (MGRS)
- * notation and coordinates.
- * */
-public interface MgrsConversionMode {
- /**
- * Uses the spheroid to determine the military grid string.
- */
- public static final int mgrsAutomatic = 0;// PE_MGRS_STYLE_AUTO
- /**
- * Treats all spheroids as new, like WGS 1984, when creating or reading a
- * military grid string. The 180 longitude falls into zone 60.
- */
- public static final int mgrsNewStyle = 0x100; // PE_MGRS_STYLE_NEW
- /**
- * Treats all spheroids as old, like Bessel 1841, when creating or reading a
- * military grid string. The 180 longitude falls into zone 60.
- */
- public static final int mgrsOldStyle = 0x200; // PE_MGRS_STYLE_OLD
- /**
- * Treats all spheroids as new, like WGS 1984, when creating or reading a
- * military grid string. The 180 longitude falls into zone 01.
- */
- public static final int mgrsNewWith180InZone01 = 0x1000 + 0x100; // PE_MGRS_180_ZONE_1_PLUS
- // |
- // PE_MGRS_STYLE_NEW
- /**
- * Treats all spheroids as old, like Bessel 1841, when creating or reading a
- * military grid string. The 180 longitude falls into zone 01.
- */
- public static final int mgrsOldWith180InZone01 = 0x1000 + 0x200; // PE_MGRS_180_ZONE_1_PLUS
- // |
- // PE_MGRS_STYLE_OLD
-}
diff --git a/src/main/java/com/esri/core/geometry/MultiPath.java b/src/main/java/com/esri/core/geometry/MultiPath.java
index 3dbda88d..48cf8bd9 100644
--- a/src/main/java/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);
}
@@ -277,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.
*
@@ -653,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);
}
@@ -724,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);
}
@@ -738,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/main/java/com/esri/core/geometry/MultiPathImpl.java b/src/main/java/com/esri/core/geometry/MultiPathImpl.java
index 33e530b6..d70e5c5d 100644
--- a/src/main/java/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,10 +25,9 @@
package com.esri.core.geometry;
-import java.util.ArrayList;
+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;
@@ -54,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;
}
@@ -136,6 +162,7 @@ public void startPath(Point point) {
throw new IllegalArgumentException();// throw new
// IllegalArgumentException();
+ mergeVertexDescription(point.getDescription());
_initPathStartPoint();
point.copyTo(m_moveToPoint);
@@ -1632,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(),
@@ -1676,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);
}
@@ -1846,7 +1871,8 @@ void _copyToImpl(MultiVertexGeometryImpl dst) {
MultiPathImpl dstPoly = (MultiPathImpl) dst;
dstPoly.m_bPathStarted = false;
dstPoly.m_curveParamwritePoint = m_curveParamwritePoint;
-
+ dstPoly.m_fill_rule = m_fill_rule;
+
if (m_paths != null)
dstPoly.m_paths = new AttributeStreamOfInt32(m_paths);
else
@@ -1922,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);
}
@@ -2095,27 +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
@@ -2508,6 +2553,30 @@ void queryPathEnvelope2D(int path_index, Envelope2D envelope) {
}
}
+ 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) {
if (m_accelerators == null)// (!m_accelerators)
@@ -2524,22 +2593,34 @@ public boolean _buildQuadTreeAccelerator(GeometryAccelerationDegree d) {
return true;
}
- boolean _buildPathEnvelopesAccelerator(GeometryAccelerationDegree d) {
+ boolean _buildQuadTreeForPathsAccelerator(GeometryAccelerationDegree degree) {
if (m_accelerators == null) {
m_accelerators = new GeometryAccelerators();
}
- ArrayList path_envelopes = new ArrayList(0);
+ // TODO: when less than two envelopes - no need to this.
- for (int ipath = 0; ipath < getPathCount(); ipath++) {
- Envelope2D env = new Envelope2D();
- queryPathEnvelope2D(ipath, env);
- path_envelopes.add(env);
- }
+ if (m_accelerators.getQuadTreeForPaths() != null)
+ return true;
- m_accelerators._setPathEnvelopes(path_envelopes);
+ 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/main/java/com/esri/core/geometry/MultiPoint.java b/src/main/java/com/esri/core/geometry/MultiPoint.java
index e890cb8a..4beca5b5 100644
--- a/src/main/java/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;
@@ -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.
*
@@ -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);
}
@@ -364,4 +381,9 @@ public int getStateFlag() {
public Geometry getBoundary() {
return m_impl.getBoundary();
}
+
+ @Override
+ public void replaceNaNs(int semantics, double value) {
+ m_impl.replaceNaNs(semantics, value);
+ }
}
diff --git a/src/main/java/com/esri/core/geometry/MultiPointImpl.java b/src/main/java/com/esri/core/geometry/MultiPointImpl.java
index b29e35c3..bb16671f 100644
--- a/src/main/java/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;
diff --git a/src/main/java/com/esri/core/geometry/MultiVertexGeometry.java b/src/main/java/com/esri/core/geometry/MultiVertexGeometry.java
index 51948f74..c164b48c 100644
--- a/src/main/java/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.
@@ -197,7 +197,7 @@ abstract void setAttribute(int semantics, int index, int ordinate,
* 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.
@@ -214,6 +214,6 @@ 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/main/java/com/esri/core/geometry/MultiVertexGeometryImpl.java b/src/main/java/com/esri/core/geometry/MultiVertexGeometryImpl.java
index fc614cfb..e045aa2a 100644
--- a/src/main/java/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");
@@ -960,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);
@@ -972,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));
}
}
}
@@ -993,8 +961,6 @@ public Point getPoint(int index) {
Point outPoint = new Point();
outPoint.assignVertexDescription(m_description);
- if (outPoint.isEmpty())
- outPoint._setToDefault();
for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
@@ -1068,12 +1034,51 @@ public void queryCoordinates(Point3D[] dst) {
dst[i] = getXYZ(i);
}
}
+
+ @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
index b8d9d029..87d95111 100644
--- a/src/main/java/com/esri/core/geometry/NonSimpleResult.java
+++ b/src/main/java/com/esri/core/geometry/NonSimpleResult.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,37 +23,65 @@
*/
package com.esri.core.geometry;
-class NonSimpleResult {
+/**
+ * The result of the IsSimpleXXX.
+ *
+ *
+ */
+public class NonSimpleResult {
public enum Reason {
- NotDetermined, // >> 32));
return hash(hc);
}
+ //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);
@@ -93,6 +101,7 @@ static int hash(int hashIn, int n) {
return hash;
}
+ //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));
@@ -127,5 +136,18 @@ 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/main/java/com/esri/core/geometry/OGCStructure.java b/src/main/java/com/esri/core/geometry/OGCStructure.java
index 14dde139..9f0875b9 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/ObjectCacheTable.java b/src/main/java/com/esri/core/geometry/ObjectCacheTable.java
index b655ed70..54b18abd 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/Operator.java b/src/main/java/com/esri/core/geometry/Operator.java
index 41f69129..6866fb16 100644
--- a/src/main/java/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.
@@ -36,12 +36,11 @@ public enum Type {
Project,
ExportToJson, ImportFromJson,
- @Deprecated ImportMapGeometryFromJson,
ExportToESRIShape, ImportFromESRIShape,
Union, Difference,
- Proximity2D,
+ Proximity2D, Centroid2D,
Relate, Equals, Disjoint, Intersects, Within, Contains, Crosses, Touches, Overlaps,
diff --git a/src/main/java/com/esri/core/geometry/OperatorBoundary.java b/src/main/java/com/esri/core/geometry/OperatorBoundary.java
index fd34bea1..e2a8fc1c 100644
--- a/src/main/java/com/esri/core/geometry/OperatorBoundary.java
+++ b/src/main/java/com/esri/core/geometry/OperatorBoundary.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/OperatorBoundaryLocal.java b/src/main/java/com/esri/core/geometry/OperatorBoundaryLocal.java
index 585ded53..0188affd 100644
--- a/src/main/java/com/esri/core/geometry/OperatorBoundaryLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorBoundaryLocal.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/OperatorBoundaryLocalCursor.java b/src/main/java/com/esri/core/geometry/OperatorBoundaryLocalCursor.java
index fa01fe80..c06c3d53 100644
--- a/src/main/java/com/esri/core/geometry/OperatorBoundaryLocalCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorBoundaryLocalCursor.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/OperatorBuffer.java b/src/main/java/com/esri/core/geometry/OperatorBuffer.java
index 2b8f02b4..4150a9f9 100644
--- a/src/main/java/com/esri/core/geometry/OperatorBuffer.java
+++ b/src/main/java/com/esri/core/geometry/OperatorBuffer.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.
@@ -58,6 +58,31 @@ public abstract Geometry execute(Geometry inputGeometry,
SpatialReference sr, double distance,
ProgressTracker progressTracker);
+ /**
+ *Creates a buffer around the input geometries
+ *
+ *@param input_geometries The geometries to buffer.
+ *@param sr The Spatial_reference of the Geometries. It is used to obtain the tolerance. Can be null.
+ *@param distances The buffer distances 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 max_deviation The max deviation of the result buffer from the true buffer in the units of the sr.
+ *When max_deviation is NaN or 0, it is replaced with 1e-5 * abs(distance).
+ *When max_deviation is larger than MIN = 0.5 * abs(distance), it is replaced with MIN. See below for more information.
+ *@param max_vertices_in_full_circle The maximum number of vertices in polygon produced from a buffered point. A value of 96 is used in methods that do not accept max_vertices_in_full_circle.
+ *If the value is less than MIN=12, it is set to MIN. See below for more information.
+ *@param b_union If True, the buffered geometries will be unioned, otherwise they wont be unioned.
+ *@param progress_tracker The progress tracker that allows to cancel the operation. Pass null if not needed.
+ *
+ *The max_deviation and max_vertices_in_full_circle control the quality of round joins in the buffer. That is, the precision of the buffer is max_deviation unless
+ *the number of required vertices is too large.
+ *The max_vertices_in_full_circle controls how many vertices can be in each round join in the buffer. It is approximately equal to the number of vertices in the polygon around a
+ *buffered point. It has a priority over max_deviation. The max deviation is the distance from the result polygon to a true buffer.
+ *The real deviation is calculated as the max(max_deviation, abs(distance) * (1 - cos(PI / max_vertex_in_complete_circle))).
+ *
+ *Note that max_deviation can be exceeded because geometry is generalized with 0.25 * real_deviation, also input segments closer than 0.25 * real_deviation are
+ *snapped to a point.
+ */
+ public abstract GeometryCursor execute(GeometryCursor input_geometries, SpatialReference sr, double[] distances, double max_deviation, int max_vertices_in_full_circle, boolean b_union, ProgressTracker progress_tracker);
+
public static OperatorBuffer local() {
return (OperatorBuffer) OperatorFactoryLocal.getInstance().getOperator(
Type.Buffer);
diff --git a/src/main/java/com/esri/core/geometry/OperatorBufferCursor.java b/src/main/java/com/esri/core/geometry/OperatorBufferCursor.java
index a779db3a..dd5716ca 100644
--- a/src/main/java/com/esri/core/geometry/OperatorBufferCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorBufferCursor.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,25 +25,29 @@
package com.esri.core.geometry;
class OperatorBufferCursor extends GeometryCursor {
-
+ Bufferer m_bufferer = new Bufferer();
private GeometryCursor m_inputGeoms;
private SpatialReferenceImpl m_Spatial_reference;
private ProgressTracker m_progress_tracker;
private double[] m_distances;
private Envelope2D m_currentUnionEnvelope2D;
- private boolean m_bUnion;
-
+ double m_max_deviation;
+ int m_max_vertices_in_full_circle;
private int m_index;
private int m_dindex;
OperatorBufferCursor(GeometryCursor inputGeoms, SpatialReference sr,
- double[] distances, boolean b_union,
+ double[] distances,
+ double max_deviation,
+ int max_vertices,
+ boolean b_union,
ProgressTracker progress_tracker) {
m_index = -1;
m_inputGeoms = inputGeoms;
+ m_max_deviation = max_deviation;
+ m_max_vertices_in_full_circle = max_vertices;
m_Spatial_reference = (SpatialReferenceImpl) (sr);
m_distances = distances;
- m_bUnion = b_union;
m_currentUnionEnvelope2D = new Envelope2D();
m_currentUnionEnvelope2D.setEmpty();
m_dindex = -1;
@@ -72,7 +76,7 @@ public int getGeometryID() {
// virtual bool IsRecycling() OVERRIDE { return false; }
Geometry buffer(Geometry geom, double distance) {
- return Bufferer.buffer(geom, distance, m_Spatial_reference,
- NumberUtils.TheNaN, 96, m_progress_tracker);
+ return m_bufferer.buffer(geom, distance, m_Spatial_reference,
+ m_max_deviation, m_max_vertices_in_full_circle, m_progress_tracker);
}
}
diff --git a/src/main/java/com/esri/core/geometry/OperatorBufferLocal.java b/src/main/java/com/esri/core/geometry/OperatorBufferLocal.java
index 86f7e6bb..8c44225f 100644
--- a/src/main/java/com/esri/core/geometry/OperatorBufferLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorBufferLocal.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,15 +30,8 @@ class OperatorBufferLocal extends OperatorBuffer {
public GeometryCursor execute(GeometryCursor inputGeometries,
SpatialReference sr, double[] distances, boolean bUnion,
ProgressTracker progressTracker) {
- if (bUnion) {
- OperatorBufferCursor cursor = new OperatorBufferCursor(
- inputGeometries, sr, distances, false, progressTracker);
- return ((OperatorUnion) OperatorFactoryLocal.getInstance()
- .getOperator(Operator.Type.Union)).execute(cursor, sr,
- progressTracker);
- } else
- return new OperatorBufferCursor(inputGeometries, sr, distances,
- false, progressTracker);
+ return execute(inputGeometries, sr, distances, NumberUtils.NaN(), 96,
+ bUnion, progressTracker);
}
@Override
@@ -54,4 +47,20 @@ public Geometry execute(Geometry inputGeometry, SpatialReference sr,
return outputCursor.next();
}
+ @Override
+ public GeometryCursor execute(GeometryCursor inputGeometries,
+ SpatialReference sr, double[] distances, double max_deviation,
+ int max_vertices_in_full_circle, boolean b_union,
+ ProgressTracker progressTracker) {
+ if (b_union) {
+ OperatorBufferCursor cursor = new OperatorBufferCursor(
+ inputGeometries, sr, distances, max_deviation,
+ max_vertices_in_full_circle, false, progressTracker);
+ return OperatorUnion.local().execute(cursor, sr, progressTracker);// (int)Operator_union::Options::enum_disable_edge_dissolver
+ } else {
+ return new OperatorBufferCursor(inputGeometries, sr, distances,
+ max_deviation, max_vertices_in_full_circle, false,
+ progressTracker);
+ }
+ }
}
diff --git a/src/main/java/com/esri/core/geometry/OperatorCentroid2D.java b/src/main/java/com/esri/core/geometry/OperatorCentroid2D.java
new file mode 100644
index 00000000..9453053d
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorCentroid2D.java
@@ -0,0 +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;
+
+public abstract class OperatorCentroid2D extends Operator {
+ @Override
+ public Type getType() {
+ return Type.Centroid2D;
+ }
+
+ public abstract Point2D execute(Geometry geometry, ProgressTracker progressTracker);
+
+ public static OperatorCentroid2D local() {
+ return (OperatorCentroid2D) OperatorFactoryLocal.getInstance().getOperator(Type.Centroid2D);
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorCentroid2DLocal.java b/src/main/java/com/esri/core/geometry/OperatorCentroid2DLocal.java
new file mode 100644
index 00000000..ce7079b8
--- /dev/null
+++ b/src/main/java/com/esri/core/geometry/OperatorCentroid2DLocal.java
@@ -0,0 +1,143 @@
+/*
+ Copyright 1995-2019 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 OperatorCentroid2DLocal extends OperatorCentroid2D {
+ @Override
+ public Point2D execute(Geometry geometry, ProgressTracker progressTracker) {
+ if (geometry.isEmpty()) {
+ return null;
+ }
+
+ Geometry.Type geometryType = geometry.getType();
+ switch (geometryType) {
+ case Point:
+ return ((Point) geometry).getXY();
+ case Line:
+ return computeLineCentroid((Line) geometry);
+ case Envelope:
+ return ((Envelope) geometry).getCenterXY();
+ case MultiPoint:
+ return computePointsCentroid((MultiPoint) geometry);
+ case Polyline:
+ return computePolylineCentroid(((Polyline) geometry));
+ case Polygon:
+ return computePolygonCentroid((Polygon) geometry);
+ default:
+ throw new UnsupportedOperationException("Unexpected geometry type: " + geometryType);
+ }
+ }
+
+ private static Point2D computeLineCentroid(Line line) {
+ return new Point2D((line.getEndX() - line.getStartX()) / 2, (line.getEndY() - line.getStartY()) / 2);
+ }
+
+ // Points centroid is arithmetic mean of the input points
+ private static Point2D computePointsCentroid(MultiVertexGeometry multiPoint) {
+ double xSum = 0;
+ double ySum = 0;
+ int pointCount = multiPoint.getPointCount();
+ Point2D point2D = new Point2D();
+ for (int i = 0; i < pointCount; i++) {
+ multiPoint.getXY(i, point2D);
+ xSum += point2D.x;
+ ySum += point2D.y;
+ }
+ return new Point2D(xSum / pointCount, ySum / pointCount);
+ }
+
+ // Lines centroid is weighted mean of each line segment, weight in terms of line
+ // length
+ private static Point2D computePolylineCentroid(MultiPath polyline) {
+ double totalLength = polyline.calculateLength2D();
+ if (totalLength == 0) {
+ return computePointsCentroid(polyline);
+ }
+
+ MathUtils.KahanSummator xSum = new MathUtils.KahanSummator(0);
+ MathUtils.KahanSummator ySum = new MathUtils.KahanSummator(0);
+ Point2D point = new Point2D();
+ SegmentIterator iter = polyline.querySegmentIterator();
+ while (iter.nextPath()) {
+ while (iter.hasNextSegment()) {
+ Segment seg = iter.nextSegment();
+ seg.getCoord2D(0.5, point);
+ double length = seg.calculateLength2D();
+ point.scale(length);
+ xSum.add(point.x);
+ ySum.add(point.y);
+ }
+ }
+
+ return new Point2D(xSum.getResult() / totalLength, ySum.getResult() / totalLength);
+ }
+
+ // Polygon centroid: area weighted average of centroids
+ private static Point2D computePolygonCentroid(Polygon polygon) {
+ double totalArea = polygon.calculateArea2D();
+ if (totalArea == 0)
+ {
+ return computePolylineCentroid(polygon);
+ }
+
+ MathUtils.KahanSummator xSum = new MathUtils.KahanSummator(0);
+ MathUtils.KahanSummator ySum = new MathUtils.KahanSummator(0);
+ Point2D startPoint = new Point2D();
+ Point2D current = new Point2D();
+ Point2D next = new Point2D();
+ Point2D origin = polygon.getXY(0);
+
+ for (int ipath = 0, npaths = polygon.getPathCount(); ipath < npaths; ipath++) {
+ int startIndex = polygon.getPathStart(ipath);
+ int endIndex = polygon.getPathEnd(ipath);
+ int pointCount = endIndex - startIndex;
+ if (pointCount < 3) {
+ continue;
+ }
+
+ polygon.getXY(startIndex, startPoint);
+ polygon.getXY(startIndex + 1, current);
+ current.sub(startPoint);
+ for (int i = startIndex + 2, n = endIndex; i < n; i++) {
+ polygon.getXY(i, next);
+ next.sub(startPoint);
+ double twiceTriangleArea = next.x * current.y - current.x * next.y;
+ xSum.add((current.x + next.x) * twiceTriangleArea);
+ ySum.add((current.y + next.y) * twiceTriangleArea);
+ current.setCoords(next);
+ }
+
+ startPoint.sub(origin);
+ startPoint.scale(6.0 * polygon.calculateRingArea2D(ipath));
+ //add weighted startPoint
+ xSum.add(startPoint.x);
+ ySum.add(startPoint.y);
+ }
+
+ totalArea *= 6.0;
+ Point2D res = new Point2D(xSum.getResult() / totalArea, ySum.getResult() / totalArea);
+ res.add(origin);
+ return res;
+ }
+}
diff --git a/src/main/java/com/esri/core/geometry/OperatorClip.java b/src/main/java/com/esri/core/geometry/OperatorClip.java
index 2dca9085..8b1907af 100644
--- a/src/main/java/com/esri/core/geometry/OperatorClip.java
+++ b/src/main/java/com/esri/core/geometry/OperatorClip.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/OperatorClipCursor.java b/src/main/java/com/esri/core/geometry/OperatorClipCursor.java
index 04c8ef7e..f45484fa 100644
--- a/src/main/java/com/esri/core/geometry/OperatorClipCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorClipCursor.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/OperatorClipLocal.java b/src/main/java/com/esri/core/geometry/OperatorClipLocal.java
index 50aa6216..9f201322 100644
--- a/src/main/java/com/esri/core/geometry/OperatorClipLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorClipLocal.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/OperatorContains.java b/src/main/java/com/esri/core/geometry/OperatorContains.java
index ccc21d6a..bbc4cf27 100644
--- a/src/main/java/com/esri/core/geometry/OperatorContains.java
+++ b/src/main/java/com/esri/core/geometry/OperatorContains.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/OperatorContainsLocal.java b/src/main/java/com/esri/core/geometry/OperatorContainsLocal.java
index d9ea5d24..3bc67286 100644
--- a/src/main/java/com/esri/core/geometry/OperatorContainsLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorContainsLocal.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/OperatorConvexHull.java b/src/main/java/com/esri/core/geometry/OperatorConvexHull.java
index bd9ea418..a00b5a77 100644
--- a/src/main/java/com/esri/core/geometry/OperatorConvexHull.java
+++ b/src/main/java/com/esri/core/geometry/OperatorConvexHull.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/OperatorConvexHullCursor.java b/src/main/java/com/esri/core/geometry/OperatorConvexHullCursor.java
index 8c304a62..c90c9d72 100644
--- a/src/main/java/com/esri/core/geometry/OperatorConvexHullCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorConvexHullCursor.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,8 @@ class OperatorConvexHullCursor extends GeometryCursor {
private GeometryCursor m_inputGeometryCursor;
private int m_index;
ConvexHull m_hull = new ConvexHull();
-
- OperatorConvexHullCursor(boolean b_merge, GeometryCursor geoms,
- ProgressTracker progress_tracker) {
+
+ OperatorConvexHullCursor(boolean b_merge, GeometryCursor geoms, ProgressTracker progress_tracker) {
m_index = -1;
if (geoms == null)
throw new IllegalArgumentException();
@@ -47,8 +46,7 @@ class OperatorConvexHullCursor extends GeometryCursor {
public Geometry next() {
if (m_b_merge) {
if (!m_b_done) {
- Geometry result = calculateConvexHullMerging_(
- m_inputGeometryCursor, m_progress_tracker);
+ Geometry result = calculateConvexHullMerging_(m_inputGeometryCursor, m_progress_tracker);
m_b_done = true;
return result;
}
@@ -74,8 +72,7 @@ public int getGeometryID() {
return m_index;
}
- private Geometry calculateConvexHullMerging_(GeometryCursor geoms,
- ProgressTracker progress_tracker) {
+ private Geometry calculateConvexHullMerging_(GeometryCursor geoms, ProgressTracker progress_tracker) {
Geometry geometry;
while ((geometry = geoms.next()) != null)
@@ -83,20 +80,19 @@ private Geometry calculateConvexHullMerging_(GeometryCursor geoms,
return m_hull.getBoundingGeometry();
}
-
+
@Override
public boolean tock() {
if (m_b_done)
return true;
-
- if (!m_b_merge)
- {
+
+ if (!m_b_merge) {
//Do not use tick/tock with the non-merging convex hull.
//Call tick/next instead,
//because tick pushes geometry into the cursor, and next performs a single convex hull on it.
throw new GeometryException("Invalid call for non merging convex hull.");
}
-
+
Geometry geometry = m_inputGeometryCursor.next();
if (geometry != null) {
m_hull.addGeometry(geometry);
@@ -106,33 +102,64 @@ public boolean tock() {
}
}
- static Geometry calculateConvexHull_(Geometry geom,
- ProgressTracker progress_tracker) {
- if (isConvex_(geom, progress_tracker))
- return geom;
-
- int type = geom.getType().value();
+ static Geometry calculateConvexHull_(Geometry geom, ProgressTracker progress_tracker) {
+ if (geom.isEmpty())
+ return geom.createInstance();
- if (MultiPath.isSegment(type)) {
- Polyline polyline = new Polyline(geom.getDescription());
- polyline.addSegment((Segment) geom, true);
- return polyline;
- }
+ Geometry.Type type = geom.getType();
- if (type == Geometry.GeometryType.MultiPoint) {
- MultiPoint multi_point = (MultiPoint) geom;
- if (multi_point.getPointCount() == 2) {
+ if (Geometry.isSegment(type.value())) {// Segments are always returned either as a Point or Polyline
+ Segment segment = (Segment) geom;
+ if (segment.getStartXY().equals(segment.getEndXY())) {
+ Point point = new Point();
+ segment.queryStart(point);
+ return point;
+ } else {
+ Point pt = new Point();
+ Polyline polyline = new Polyline(geom.getDescription());
+ segment.queryStart(pt);
+ polyline.startPath(pt);
+ segment.queryEnd(pt);
+ polyline.lineTo(pt);
+ return polyline;
+ }
+ } else if (type == Geometry.Type.Envelope) {
+ Envelope envelope = (Envelope) geom;
+ Envelope2D env = new Envelope2D();
+ envelope.queryEnvelope2D(env);
+ if (env.xmin == env.xmax && env.ymin == env.ymax) {
+ Point point = new Point();
+ envelope.queryCornerByVal(0, point);
+ return point;
+ } else if (env.xmin == env.xmax || env.ymin == env.ymax) {
Point pt = new Point();
Polyline polyline = new Polyline(geom.getDescription());
- multi_point.getPointByVal(0, pt);
+ envelope.queryCornerByVal(0, pt);
polyline.startPath(pt);
- multi_point.getPointByVal(1, pt);
+ envelope.queryCornerByVal(1, pt);
polyline.lineTo(pt);
return polyline;
+ } else {
+ Polygon polygon = new Polygon(geom.getDescription());
+ polygon.addEnvelope(envelope, false);
+ return polygon;
}
}
- Polygon convex_hull = ConvexHull.construct((MultiVertexGeometry) geom);
+ if (isConvex_(geom, progress_tracker)) {
+ if (type == Geometry.Type.MultiPoint) {// Downgrade to a Point for simplistic output
+ MultiPoint multi_point = (MultiPoint) geom;
+ Point point = new Point();
+ multi_point.getPointByVal(0, point);
+ return point;
+ }
+
+ return geom;
+ }
+
+ assert (Geometry.isMultiVertex(type.value()));
+
+ Geometry convex_hull = ConvexHull.construct((MultiVertexGeometry) geom);
return convex_hull;
}
@@ -140,44 +167,52 @@ static boolean isConvex_(Geometry geom, ProgressTracker progress_tracker) {
if (geom.isEmpty())
return true; // vacuously true
- int type = geom.getType().value();
+ Geometry.Type type = geom.getType();
- if (type == Geometry.GeometryType.Point)
+ if (type == Geometry.Type.Point)
return true; // vacuously true
- if (type == Geometry.GeometryType.Envelope)
- return true; // always convex
+ if (type == Geometry.Type.Envelope) {
+ Envelope envelope = (Envelope) geom;
+ if (envelope.getXMin() == envelope.getXMax() || envelope.getYMin() == envelope.getYMax())
+ return false;
- if (MultiPath.isSegment(type))
- return false; // upgrade to polyline
+ return true;
+ }
- if (type == Geometry.GeometryType.MultiPoint) {
+ if (MultiPath.isSegment(type.value())) {
+ Segment segment = (Segment) geom;
+ if (segment.getStartXY().equals(segment.getEndXY()))
+ return false;
+
+ return true; // true, but we will upgrade to a Polyline for the ConvexHull operation
+ }
+
+ if (type == Geometry.Type.MultiPoint) {
MultiPoint multi_point = (MultiPoint) geom;
if (multi_point.getPointCount() == 1)
- return true; // vacuously true
+ return true; // vacuously true, but we will downgrade to a Point for the ConvexHull operation
- return false; // upgrade to polyline if point count is 2, otherwise
- // create convex hull
+ return false;
}
- if (type == Geometry.GeometryType.Polyline) {
+ if (type == Geometry.Type.Polyline) {
Polyline polyline = (Polyline) geom;
- if (polyline.getPathCount() == 1 && polyline.getPointCount() <= 2)
- return true; // vacuously true
+ if (polyline.getPathCount() == 1 && polyline.getPointCount() == 2) {
+ if (!polyline.getXY(0).equals(polyline.getXY(1)))
+ return true; // vacuously true
+ }
return false; // create convex hull
}
Polygon polygon = (Polygon) geom;
- if (polygon.getPathCount() != 1)
+ if (polygon.getPathCount() != 1 || polygon.getPointCount() < 3)
return false;
- if (polygon.getPointCount() <= 2)
- return true; // vacuously true
-
return ConvexHull.isPathConvex(polygon, 0, progress_tracker);
}
}
diff --git a/src/main/java/com/esri/core/geometry/OperatorConvexHullLocal.java b/src/main/java/com/esri/core/geometry/OperatorConvexHullLocal.java
index 155313a7..e314d34e 100644
--- a/src/main/java/com/esri/core/geometry/OperatorConvexHullLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorConvexHullLocal.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/OperatorCrosses.java b/src/main/java/com/esri/core/geometry/OperatorCrosses.java
index 3a354bc5..0780879a 100644
--- a/src/main/java/com/esri/core/geometry/OperatorCrosses.java
+++ b/src/main/java/com/esri/core/geometry/OperatorCrosses.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/OperatorCrossesLocal.java b/src/main/java/com/esri/core/geometry/OperatorCrossesLocal.java
index d5b55abb..2c167080 100644
--- a/src/main/java/com/esri/core/geometry/OperatorCrossesLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorCrossesLocal.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/OperatorCut.java b/src/main/java/com/esri/core/geometry/OperatorCut.java
index 59c5b589..762db7d6 100644
--- a/src/main/java/com/esri/core/geometry/OperatorCut.java
+++ b/src/main/java/com/esri/core/geometry/OperatorCut.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/OperatorCutCursor.java b/src/main/java/com/esri/core/geometry/OperatorCutCursor.java
index 266bdd99..cd5dae6c 100644
--- a/src/main/java/com/esri/core/geometry/OperatorCutCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorCutCursor.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/OperatorCutLocal.java b/src/main/java/com/esri/core/geometry/OperatorCutLocal.java
index 98613301..75dccf2c 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDensifyByLength.java b/src/main/java/com/esri/core/geometry/OperatorDensifyByLength.java
index c01ec80d..d9d9d692 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDensifyByLengthCursor.java b/src/main/java/com/esri/core/geometry/OperatorDensifyByLengthCursor.java
index b634ff59..3a7267aa 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorDensifyByLengthLocal.java b/src/main/java/com/esri/core/geometry/OperatorDensifyByLengthLocal.java
index dbffbf4b..f6eb5e0a 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDifference.java b/src/main/java/com/esri/core/geometry/OperatorDifference.java
index 11c1295a..5e4b40e6 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorDifferenceCursor.java b/src/main/java/com/esri/core/geometry/OperatorDifferenceCursor.java
index 021d1512..8c2419af 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDifferenceLocal.java b/src/main/java/com/esri/core/geometry/OperatorDifferenceLocal.java
index 2121729b..31db5027 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDisjoint.java b/src/main/java/com/esri/core/geometry/OperatorDisjoint.java
index 9892661b..9404759f 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDisjointLocal.java b/src/main/java/com/esri/core/geometry/OperatorDisjointLocal.java
index e65c0b3e..5bbaa1a2 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDistance.java b/src/main/java/com/esri/core/geometry/OperatorDistance.java
index 206bbf93..d29c2c43 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorDistanceLocal.java b/src/main/java/com/esri/core/geometry/OperatorDistanceLocal.java
index 76ac6a35..9cb35c69 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorEquals.java b/src/main/java/com/esri/core/geometry/OperatorEquals.java
index 7fb1d5b7..2fb6d3ba 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorEqualsLocal.java b/src/main/java/com/esri/core/geometry/OperatorEqualsLocal.java
index d265c55a..d5edf302 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorExportToESRIShape.java b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShape.java
index 840a1707..56aa754b 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeCursor.java
index 13d821ed..67d4dfce 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToESRIShapeLocal.java
index 9704054e..5b21e632 100644
--- a/src/main/java/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
index 9a1ac765..6f9d506c 100644
--- a/src/main/java/com/esri/core/geometry/OperatorExportToGeoJson.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJson.java
@@ -3,7 +3,7 @@
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
+ 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,
@@ -28,21 +28,53 @@
*Export to GeoJson format.
*/
public abstract class OperatorExportToGeoJson extends Operator {
- @Override
- public Type getType() {
- return Type.ExportToGeoJson;
- }
+ @Override
+ public Type getType() {
+ return Type.ExportToGeoJson;
+ }
- 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 geometryCursor The cursor of geometries to write as GeoJson.
+ * @return Returns a JsonCursor.
+ */
+ public abstract JsonCursor execute(SpatialReference spatialReference, GeometryCursor geometryCursor);
- public abstract String execute(SpatialReference spatialReference, Geometry geometry);
+ /**
+ * 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);
- public abstract String execute(int exportFlags, SpatialReference spatialReference, Geometry geometry);
-
- public abstract String execute(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);
- public static OperatorExportToGeoJson local() {
- return (OperatorExportToGeoJson) OperatorFactoryLocal.getInstance()
- .getOperator(Type.ExportToGeoJson);
- }
+ /**
+ * 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
index ddad1662..0678cef4 100644
--- a/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonCursor.java
@@ -1,9 +1,32 @@
+/*
+ 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
+ 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,
@@ -23,312 +46,757 @@
package com.esri.core.geometry;
import com.esri.core.geometry.VertexDescription.Semantics;
-import java.io.IOException;
-import java.io.StringWriter;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerationException;
-import org.codehaus.jackson.JsonGenerator;
class OperatorExportToGeoJsonCursor extends JsonCursor {
- GeometryCursor m_inputGeometryCursor;
- int m_index;
- int m_wkid = -1;
- int m_latest_wkid = -1;
- String m_wkt = null;
- boolean m_preferMulti = false;
-
- private static JsonFactory factory = new JsonFactory();
-
- public OperatorExportToGeoJsonCursor(boolean preferMulti, SpatialReference spatialReference, GeometryCursor geometryCursor) {
- m_index = -1;
- if (geometryCursor == null)
- throw new IllegalArgumentException();
- if (spatialReference != null && !spatialReference.isLocal()) {
- m_wkid = spatialReference.getOldID();
- m_wkt = spatialReference.getText();
- m_latest_wkid = spatialReference.getLatestID();
- }
- m_inputGeometryCursor = geometryCursor;
- m_preferMulti = preferMulti;
- }
-
- public OperatorExportToGeoJsonCursor(GeometryCursor geometryCursor) {
- m_index = -1;
-
- if (geometryCursor == null)
- throw new IllegalArgumentException();
-
- 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(geometry);
- }
- return null;
- }
-
- private String exportToGeoJson(Geometry geometry) {
- StringWriter sw = new StringWriter();
-
- try {
- JsonGenerator g = factory.createJsonGenerator(sw);
-
- int type = geometry.getType().value();
-
- switch (type) {
- case Geometry.GeometryType.Point:
- exportPointToGeoJson(g, (Point) geometry);
- break;
- case Geometry.GeometryType.MultiPoint:
- exportMultiPointToGeoJson(g, (MultiPoint) geometry);
- break;
- case Geometry.GeometryType.Polyline:
- exportMultiPathToGeoJson(g, (Polyline) geometry);
- break;
- case Geometry.GeometryType.Polygon:
- exportMultiPathToGeoJson(g, (Polygon) geometry);
- break;
- case Geometry.GeometryType.Envelope:
- exportEnvelopeToGeoJson(g, (Envelope) geometry);
- break;
- default:
- throw new RuntimeException("not implemented for this geometry type");
- }
-
- return sw.getBuffer().toString();
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- }
-
- private void exportPointToGeoJson(JsonGenerator g, Point p) throws JsonGenerationException, IOException {
- if (m_preferMulti) {
- MultiPoint mp = new MultiPoint();
- mp.add(p);
- exportMultiPointToGeoJson(g, mp);
- return;
- }
-
- g.writeStartObject();
-
- g.writeFieldName("type");
- g.writeString("Point");
-
- g.writeFieldName("coordinates");
-
- if (p.isEmpty()) {
- g.writeNull();
- } else {
- g.writeStartArray();
-
- writeDouble(p.getX(), g);
- writeDouble(p.getY(), g);
-
- if (p.hasAttribute(Semantics.Z))
- writeDouble(p.getZ(), g);
-
- g.writeEndArray();
- }
-
- g.writeEndObject();
- g.close();
- }
-
- private void exportMultiPointToGeoJson(JsonGenerator g, MultiPoint mp) throws JsonGenerationException, IOException {
- g.writeStartObject();
-
- g.writeFieldName("type");
- g.writeString("MultiPoint");
-
- g.writeFieldName("coordinates");
-
- if (mp.isEmpty()) {
- g.writeNull();
- } else {
- g.writeStartArray();
-
- MultiPointImpl mpImpl = (MultiPointImpl) mp._getImpl();
- AttributeStreamOfDbl zs = mp.hasAttribute(Semantics.Z) ? (AttributeStreamOfDbl) mpImpl.getAttributeStreamRef(Semantics.Z) : null;
-
- Point2D p = new Point2D();
-
- int n = mp.getPointCount();
-
- for(int i = 0; i < n; i++) {
- mp.getXY(i, p);
-
- g.writeStartArray();
-
- writeDouble(p.x, g);
- writeDouble(p.y, g);
-
- if (zs != null)
- writeDouble(zs.get(i), g);
-
- g.writeEndArray();
- }
-
- g.writeEndArray();
- }
-
- g.writeEndObject();
- g.close();
- }
-
- private void exportMultiPathToGeoJson(JsonGenerator g, MultiPath p) throws JsonGenerationException, IOException {
- MultiPathImpl pImpl = (MultiPathImpl) p._getImpl();
-
- boolean isPolygon = pImpl.m_bPolygon;
- int polyCount = isPolygon ? pImpl.getOGCPolygonCount() : 0;
-
- // check yo' polys playa
-
- g.writeStartObject();
-
- g.writeFieldName("type");
-
- boolean bCollection = false;
- if (isPolygon) {
- if (polyCount >= 2 || m_preferMulti) { // single polys seem to have a polyCount of 0, multi polys seem to be >= 2
- g.writeString("MultiPolygon");
- bCollection = true;
- } else {
- g.writeString("Polygon");
- }
- }
- else {
- if (p.getPathCount() > 1 || m_preferMulti) { // single polys seem to have a polyCount of 0, multi polys seem to be >= 2
- g.writeString("MultiLineString");
- bCollection = true;
- } else {
- g.writeString("LineString");
- }
- }
-
- g.writeFieldName("coordinates");
-
- if (p.isEmpty()) {
- g.writeNull();
- } else {
- exportMultiPathToGeoJson(g, pImpl, bCollection);
- }
+ 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();
- g.writeEndObject();
- g.close();
- }
-
- private void exportMultiPathToGeoJson(JsonGenerator g, MultiPathImpl pImpl, boolean bCollection) throws IOException {
- int startIndex;
- int vertices;
-
- if (bCollection)
- g.writeStartArray();
-
- //AttributeStreamOfDbl position = (AttributeStreamOfDbl) pImpl.getAttributeStreamRef(VertexDescription.Semantics.POSITION);
- //AttributeStreamOfInt8 pathFlags = pImpl.getPathFlagsStreamRef();
- //AttributeStreamOfInt32 paths = pImpl.getPathStreamRef();
- int pathCount = pImpl.getPathCount();
- boolean isPolygon = pImpl.m_bPolygon;
- AttributeStreamOfDbl zs = pImpl.hasAttribute(Semantics.Z) ? (AttributeStreamOfDbl) pImpl.getAttributeStreamRef(Semantics.Z) : null;
-
- for (int path = 0; path < pathCount; path++) {
- startIndex = pImpl.getPathStart(path);
- vertices = pImpl.getPathSize(path);
-
- boolean isExtRing = isPolygon && pImpl.isExteriorRing(path);
- if (isExtRing) {//only for polygons
- if (path > 0)
- g.writeEndArray();//end of OGC polygon
-
- g.writeStartArray();//start of next OGC polygon
- }
-
- writePath(pImpl, g, path, startIndex, vertices, zs);
- }
-
- if (isPolygon)
- g.writeEndArray();//end of last OGC polygon
-
- if (bCollection)
- g.writeEndArray();
- }
-
- private void closePath(MultiPathImpl mp, JsonGenerator g, int startIndex, AttributeStreamOfDbl zs) throws IOException {
- Point2D pt = new Point2D();
-
- // close ring
- mp.getXY(startIndex, pt);
- g.writeStartArray();
- writeDouble(pt.x, g);
- writeDouble(pt.y, g);
-
- if (zs != null)
- writeDouble(zs.get(startIndex), g);
-
- g.writeEndArray();
- }
-
- private void writePath(MultiPathImpl mp, JsonGenerator g, int pathIndex, int startIndex, int vertices, AttributeStreamOfDbl zs) throws IOException {
- Point2D pt = new Point2D();
-
- g.writeStartArray();
-
- for (int i = startIndex; i < startIndex + vertices; i++) {
- mp.getXY(i, pt);
- g.writeStartArray();
- writeDouble(pt.x, g);
- writeDouble(pt.y, g);
-
- if (zs != null)
- writeDouble(zs.get(i), g);
-
- g.writeEndArray();
- }
-
- if (mp.isClosedPath(pathIndex))
- closePath(mp, g, startIndex, zs);
-
- g.writeEndArray();
- }
-
- private void exportEnvelopeToGeoJson(JsonGenerator g, Envelope e) throws JsonGenerationException, IOException {
- boolean empty = e.isEmpty();
-
- g.writeStartObject();
- g.writeFieldName("bbox");
-
- if (empty) {
- g.writeNull();
- } else {
- g.writeStartArray();
- writeDouble(e.getXMin(), g);
- writeDouble(e.getYMin(), g);
- writeDouble(e.getXMax(), g);
- writeDouble(e.getYMax(), g);
- g.writeEndArray();
- }
-
- g.writeEndObject();
- g.close();
- }
-
- private void writeDouble(double d, JsonGenerator g) throws IOException, JsonGenerationException {
- if (NumberUtils.isNaN(d)) {
- g.writeNull();
- } else {
- g.writeNumber(d);
- }
-
- return;
- }
+ 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
index 0abbadb5..9da02767 100644
--- a/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToGeoJsonLocal.java
@@ -3,7 +3,7 @@
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
+ 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,
@@ -23,29 +23,28 @@
package com.esri.core.geometry;
class OperatorExportToGeoJsonLocal extends OperatorExportToGeoJson {
- @Override
- public JsonCursor execute(SpatialReference spatialReference, GeometryCursor geometryCursor) {
- return new OperatorExportToGeoJsonCursor(false, spatialReference, geometryCursor);
- }
-
- @Override
- public String execute(SpatialReference spatialReference, Geometry geometry) {
- SimpleGeometryCursor gc = new SimpleGeometryCursor(geometry);
- JsonCursor cursor = new OperatorExportToGeoJsonCursor(false, spatialReference, gc);
- return cursor.next();
- }
-
- @Override
- public String execute(int exportFlags, SpatialReference spatialReference, Geometry geometry) {
- SimpleGeometryCursor gc = new SimpleGeometryCursor(geometry);
- JsonCursor cursor = new OperatorExportToGeoJsonCursor(exportFlags == GeoJsonExportFlags.geoJsonExportPreferMultiGeometry, spatialReference, gc);
- return cursor.next();
- }
-
- @Override
- public String execute(Geometry geometry) {
- SimpleGeometryCursor gc = new SimpleGeometryCursor(geometry);
- JsonCursor cursor = new OperatorExportToGeoJsonCursor(gc);
- return cursor.next();
- }
+ @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
index 9b548d4f..32bfc078 100644
--- a/src/main/java/com/esri/core/geometry/OperatorExportToJson.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToJson.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/OperatorExportToJsonCursor.java b/src/main/java/com/esri/core/geometry/OperatorExportToJsonCursor.java
index 85547549..9d24be43 100644
--- a/src/main/java/com/esri/core/geometry/OperatorExportToJsonCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToJsonCursor.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,442 +24,436 @@
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) {
- e.printStackTrace();
- }
-
- }
-
- 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.addValueDoubleF(pt.x, decimals);
- jsonWriter.addValueDoubleF(pt.y, decimals);
- } 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.addValueDoubleF(pt.x, decimals);
- jsonWriter.addValueDoubleF(pt.y, decimals);
- } 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.addValueDoubleF(pt.x, decimals);
- jsonWriter.addValueDoubleF(pt.y, decimals);
- } 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.addPairDoubleF("x", pt.getX(), decimals);
- jsonWriter.addPairDoubleF("y", pt.getY(), decimals);
- } 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.addPairDoubleF("xmin", env.getXMin(), decimals);
- jsonWriter.addPairDoubleF("ymin", env.getYMin(), decimals);
- jsonWriter.addPairDoubleF("xmax", env.getXMax(), decimals);
- jsonWriter.addPairDoubleF("ymax", env.getYMax(), decimals);
- } 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();
- }
- }
- }
+ 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
index 5c5f819d..65554574 100644
--- a/src/main/java/com/esri/core/geometry/OperatorExportToJsonLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorExportToJsonLocal.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/OperatorExportToWkb.java b/src/main/java/com/esri/core/geometry/OperatorExportToWkb.java
index d4418b2c..fba948cb 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorExportToWkbLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToWkbLocal.java
index 929e9168..a1ddec68 100644
--- a/src/main/java/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.
@@ -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/main/java/com/esri/core/geometry/OperatorExportToWkt.java b/src/main/java/com/esri/core/geometry/OperatorExportToWkt.java
index 6e893b14..10eab9b2 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorExportToWktLocal.java b/src/main/java/com/esri/core/geometry/OperatorExportToWktLocal.java
index 5fe4398f..0b3a4466 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorFactory.java b/src/main/java/com/esri/core/geometry/OperatorFactory.java
index 680cdfee..66e6030a 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorFactoryLocal.java b/src/main/java/com/esri/core/geometry/OperatorFactoryLocal.java
index a77628d3..04368b9d 100644
--- a/src/main/java/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());
@@ -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) {
+ }
+ }
+ }
- JsonFactory jf = new JsonFactory();
- JsonParser jp = null;
+ MapGeometry mapGeom = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, jsonString);
+ return mapGeom;
+ }
+
+ public static MapGeometry loadGeometryFromJSONStringDbg(String json) {
+ if (json == null) {
+ throw new IllegalArgumentException();
+ }
+
+ 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/main/java/com/esri/core/geometry/OperatorGeneralize.java b/src/main/java/com/esri/core/geometry/OperatorGeneralize.java
index af6223bd..ce8c4703 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorGeneralizeCursor.java b/src/main/java/com/esri/core/geometry/OperatorGeneralizeCursor.java
index eb860616..b0b31a5c 100644
--- a/src/main/java/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 GeometryException.GeometryInternalError();
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/main/java/com/esri/core/geometry/OperatorGeneralizeLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeneralizeLocal.java
index cf759c4b..c46e0f8c 100644
--- a/src/main/java/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
index fd0c9bdf..03cbae60 100644
--- a/src/main/java/com/esri/core/geometry/OperatorGeodesicBuffer.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodesicBuffer.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,7 +33,7 @@ public Operator.Type getType() {
/**
* Creates a geodesic buffer around the input geometries
*
- * @param input_geometries The geometries to buffer.
+ * @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.
@@ -43,13 +43,15 @@ public Operator.Type getType() {
* 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 input_geometry The geometry to buffer.
+ * @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.
@@ -57,6 +59,8 @@ public Operator.Type getType() {
* @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);
diff --git a/src/main/java/com/esri/core/geometry/OperatorGeodesicBufferLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodesicBufferLocal.java
index b3475eb9..7b9f97ba 100644
--- a/src/main/java/com/esri/core/geometry/OperatorGeodesicBufferLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodesicBufferLocal.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/OperatorGeodeticArea.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticArea.java
index 3e45ed36..ee2e0df7 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorGeodeticAreaLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticAreaLocal.java
index 441f0ec0..12a3f805 100644
--- a/src/main/java/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
index d9a660e6..ca2d1087 100644
--- a/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyByLength.java
+++ b/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyByLength.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 @@ public Type getType() {
* @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 < 1, but simply passes them along).
+ * @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.
*/
diff --git a/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyLocal.java
index 011bc4b2..f704c395 100644
--- a/src/main/java/com/esri/core/geometry/OperatorGeodeticDensifyLocal.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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorGeodeticLength.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticLength.java
index 47f79482..268dbc5c 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorGeodeticLengthLocal.java b/src/main/java/com/esri/core/geometry/OperatorGeodeticLengthLocal.java
index e878027d..306e3c74 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShape.java b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShape.java
index 32c7f778..75bc1375 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeCursor.java
index 982abe03..2db25375 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromESRIShapeLocal.java
index 4bcdd3a0..16c2013f 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorImportFromGeoJson.java b/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJson.java
index 9032c913..2a25215d 100644
--- a/src/main/java/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
index b5d0c788..78e9c8b1 100644
--- a/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJsonLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromGeoJsonLocal.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,592 +24,1296 @@
package com.esri.core.geometry;
import com.esri.core.geometry.VertexDescription.Semantics;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
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 progress_tracker)
- throws JSONException {
- JSONObject geoJsonObject = new JSONObject(geoJsonString);
- Geometry geometry = importGeometryFromGeoJson_(importFlags, type,
- geoJsonObject);
- SpatialReference spatialReference = importSpatialReferenceFromGeoJson_(geoJsonObject);
- MapGeometry mapGeometry = new MapGeometry(geometry, spatialReference);
- return mapGeometry;
+ String geoJsonString, ProgressTracker progressTracker)
+ throws JsonGeometryException {
+ MapGeometry map_geometry = OperatorImportFromGeoJsonHelper
+ .importFromGeoJson(importFlags, type, JsonParserReader.createFromString(geoJsonString), progressTracker, false);
+ return map_geometry;
}
- static JSONArray getJSONArray(JSONObject obj, String name)
- throws JSONException {
- if (obj.get(name) == JSONObject.NULL)
- return new JSONArray();
- else
- return obj.getJSONArray(name);
+ @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);
}
- @Override
- public MapOGCStructure executeOGC(int import_flags, String geoJsonString,
- ProgressTracker progress_tracker) throws JSONException {
- JSONObject geoJsonObject = new JSONObject(geoJsonString);
- ArrayList structureStack = new ArrayList(0);
- ArrayList objectStack = new ArrayList(0);
- AttributeStreamOfInt32 indices = new AttributeStreamOfInt32(0);
- AttributeStreamOfInt32 numGeometries = new AttributeStreamOfInt32(0);
-
- OGCStructure root = new OGCStructure();
- root.m_structures = new ArrayList(0);
- structureStack.add(root); // add dummy root
- objectStack.add(geoJsonObject);
- indices.add(0);
- numGeometries.add(1);
-
- while (!objectStack.isEmpty()) {
- if (indices.getLast() == numGeometries.getLast()) {
- structureStack.remove(structureStack.size() - 1);
- indices.removeLast();
- numGeometries.removeLast();
- continue;
- }
-
- OGCStructure lastStructure = structureStack.get(structureStack
- .size() - 1);
- JSONObject lastObject = objectStack.get(objectStack.size() - 1);
- objectStack.remove(objectStack.size() - 1);
- indices.write(indices.size() - 1, indices.getLast() + 1);
- String typeString = lastObject.getString("type");
-
- if (typeString.equalsIgnoreCase("GeometryCollection")) {
- OGCStructure next = new OGCStructure();
- next.m_type = 7;
- next.m_structures = new ArrayList(0);
- lastStructure.m_structures.add(next);
- structureStack.add(next);
-
- JSONArray geometries = getJSONArray(lastObject, "geometries");
- indices.add(0);
- numGeometries.add(geometries.length());
-
- for (int i = geometries.length() - 1; i >= 0; i--)
- objectStack.add(geometries.getJSONObject(i));
- } else {
- int ogcType;
-
- if (typeString.equalsIgnoreCase("Point"))
- ogcType = 1;
- else if (typeString.equalsIgnoreCase("LineString"))
- ogcType = 2;
- else if (typeString.equalsIgnoreCase("Polygon"))
- ogcType = 3;
- else if (typeString.equalsIgnoreCase("MultiPoint"))
- ogcType = 4;
- else if (typeString.equalsIgnoreCase("MultiLineString"))
- ogcType = 5;
- else if (typeString.equalsIgnoreCase("MultiPolygon"))
- ogcType = 6;
- else
- throw new UnsupportedOperationException();
-
- Geometry geometry = importGeometryFromGeoJson_(import_flags,
- Geometry.Type.Unknown, lastObject);
-
- OGCStructure leaf = new OGCStructure();
- leaf.m_type = ogcType;
- leaf.m_geometry = geometry;
- lastStructure.m_structures.add(leaf);
- }
+ 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;
}
- MapOGCStructure mapOGCStructure = new MapOGCStructure();
- mapOGCStructure.m_ogcStructure = root;
- mapOGCStructure.m_spatialReference = importSpatialReferenceFromGeoJson_(geoJsonObject);
+ 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);
+ }
- return mapOGCStructure;
- }
+ 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();
+ }
+ }
- private static SpatialReference importSpatialReferenceFromGeoJson_(
- JSONObject crsJSONObject) throws JSONException {
- String wkidString = crsJSONObject.optString("crs", "");
+ // 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 (wkidString.equals("")) {
- return SpatialReference.create(4326);
- }
+ if (!skip_coordinates && !b_geometry_collection) {
+ geometry = geo_json_helper.createGeometry_(geo_json_type,
+ type.value());
- // wkidString will be of the form "EPSG:#" where # is an integer, the
- // EPSG ID.
- // If the ID is below 32,767, then the EPSG ID will agree with the
- // well-known (WKID).
+ ms.m_ogcStructure = new OGCStructure();
+ ms.m_ogcStructure.m_type = m_ogcType;
+ ms.m_ogcStructure.m_geometry = geometry;
+ }
- if (wkidString.length() <= 5) {
- throw new IllegalArgumentException();
+ 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;
}
- // Throws a JSON exception if this cannot appropriately be converted to
- // an integer.
- int wkid = Integer.valueOf(wkidString.substring(5)).intValue();
+ // 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");
+ }
- return SpatialReference.create(wkid);
- }
+ if (coordinates_level_lower > coordinates_level_upper) {
+ throw new IllegalArgumentException("invalid argument");
+ }
- private static Geometry importGeometryFromGeoJson_(int importFlags,
- Geometry.Type type, JSONObject geometryJSONObject)
- throws JSONException {
- String typeString = geometryJSONObject.getString("type");
- JSONArray coordinateArray = getJSONArray(geometryJSONObject,
- "coordinates");
-
- if (typeString.equalsIgnoreCase("MultiPolygon")) {
- if (type != Geometry.Type.Polygon && type != Geometry.Type.Unknown)
- throw new IllegalArgumentException("invalid shapetype");
- return polygonTaggedText_(true, importFlags, coordinateArray);
- } else if (typeString.equalsIgnoreCase("MultiLineString")) {
- if (type != Geometry.Type.Polyline && type != Geometry.Type.Unknown)
- throw new IllegalArgumentException("invalid shapetype");
- return lineStringTaggedText_(true, importFlags, coordinateArray);
- } else if (typeString.equalsIgnoreCase("MultiPoint")) {
- if (type != Geometry.Type.MultiPoint
- && type != Geometry.Type.Unknown)
- throw new IllegalArgumentException("invalid shapetype");
- return multiPointTaggedText_(importFlags, coordinateArray);
- } else if (typeString.equalsIgnoreCase("Polygon")) {
- if (type != Geometry.Type.Polygon && type != Geometry.Type.Unknown)
- throw new IllegalArgumentException("invalid shapetype");
- return polygonTaggedText_(false, importFlags, coordinateArray);
- } else if (typeString.equalsIgnoreCase("LineString")) {
- if (type != Geometry.Type.Polyline && type != Geometry.Type.Unknown)
- throw new IllegalArgumentException("invalid shapetype");
- return lineStringTaggedText_(false, importFlags, coordinateArray);
- } else if (typeString.equalsIgnoreCase("Point")) {
- if (type != Geometry.Type.Point && type != Geometry.Type.Unknown)
- throw new IllegalArgumentException("invalid shapetype");
- return pointTaggedText_(importFlags, coordinateArray);
- } else {
- return null;
- }
- }
+ 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();
+ }
+ }
- private static Geometry polygonTaggedText_(boolean bMultiPolygon,
- int importFlags, JSONArray coordinateArray) throws JSONException {
- MultiPath multiPath;
- MultiPathImpl multiPathImpl;
- AttributeStreamOfDbl zs = null;
- AttributeStreamOfDbl ms = null;
- AttributeStreamOfDbl position;
- AttributeStreamOfInt32 paths;
- AttributeStreamOfInt8 path_flags;
-
- position = (AttributeStreamOfDbl) AttributeStreamBase
- .createDoubleStream(0);
- paths = (AttributeStreamOfInt32) AttributeStreamBase.createIndexStream(
- 1, 0);
- path_flags = (AttributeStreamOfInt8) AttributeStreamBase
- .createByteStream(1, (byte) 0);
-
- multiPath = new Polygon();
- multiPathImpl = (MultiPathImpl) multiPath._getImpl();
-
- int pointCount;
-
- if (bMultiPolygon) {
- pointCount = multiPolygonText_(zs, ms, position, paths, path_flags,
- coordinateArray);
- } else {
- pointCount = polygonText_(zs, ms, position, paths, path_flags, 0,
- coordinateArray);
+ 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;
}
- if (pointCount != 0) {
- assert (2 * pointCount == position.size());
- multiPathImpl.setAttributeStreamRef(
- VertexDescription.Semantics.POSITION, position);
- multiPathImpl.setPathStreamRef(paths);
- multiPathImpl.setPathFlagsStreamRef(path_flags);
+ private void readCoordinateAsPoint_(JsonReader json_iterator)
+ throws JsonGeometryException {
+ assert (isDouble_(json_iterator));
+
+ m_point = new Point();
- if (zs != null) {
- multiPathImpl.setAttributeStreamRef(
- VertexDescription.Semantics.Z, zs);
+ double x = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ double y = readDouble_(json_iterator);
+ json_iterator.nextToken();
+
+ if (NumberUtils.isNaN(y)) {
+ x = NumberUtils.NaN();
}
- if (ms != null) {
- multiPathImpl.setAttributeStreamRef(
- VertexDescription.Semantics.M, ms);
+ m_point.setXY(x, y);
+
+ if (isDouble_(json_iterator)) {
+ double z = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ m_point.setZ(z);
}
- multiPathImpl.notifyModified(MultiPathImpl.DirtyFlags.DirtyAll);
+ if (isDouble_(json_iterator)) {
+ double m = readDouble_(json_iterator);
+ json_iterator.nextToken();
+ m_point.setM(m);
+ }
- AttributeStreamOfInt8 path_flags_clone = new AttributeStreamOfInt8(
- path_flags);
+ if (json_iterator.currentToken() != JsonReader.Token.END_ARRAY) {
+ throw new JsonGeometryException("parsing error");
+ }
+ }
- 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(multiPathImpl, i))
- multiPathImpl.reversePath(i); // make clockwise
- } else {// Should be counter-clockwise
- if (InternalUtils.isClockwiseRing(multiPathImpl, i))
- multiPathImpl.reversePath(i); // make counter-clockwise
+ 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));
+ }
}
}
- multiPathImpl.setPathFlagsStreamRef(path_flags_clone);
+ 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");
+ }
}
- if ((importFlags & (int) GeoJsonImportFlags.geoJsonImportNonTrusted) == 0) {
- multiPathImpl.setIsSimple(MultiPathImpl.GeometryXSimple.Weak, 0.0,
- false);
+ 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);
+ }
}
- multiPathImpl.setDirtyOGCFlags(false);
+ private void addPathFlag_(boolean b_polygon_start) {
+ if (m_path_flags == null) {
+ m_path_flags = (AttributeStreamOfInt8) AttributeStreamBase
+ .createByteStream(0);
+ }
- return multiPath;
- }
+ if (b_polygon_start) {
+ m_path_flags
+ .add((byte) (PathFlags.enumClosed | PathFlags.enumOGCStartPolygon));
+ } else {
+ m_path_flags.add((byte) PathFlags.enumClosed);
+ }
+ }
- private static Geometry lineStringTaggedText_(boolean bMultiLineString,
- int importFlags, JSONArray coordinateArray) throws JSONException {
- MultiPath multiPath;
- MultiPathImpl multiPathImpl;
- AttributeStreamOfDbl zs = null;
- AttributeStreamOfDbl ms = null;
- AttributeStreamOfDbl position;
- AttributeStreamOfInt32 paths;
- AttributeStreamOfInt8 path_flags;
-
- position = (AttributeStreamOfDbl) AttributeStreamBase
- .createDoubleStream(0);
- paths = (AttributeStreamOfInt32) AttributeStreamBase.createIndexStream(
- 1, 0);
- path_flags = (AttributeStreamOfInt8) AttributeStreamBase
- .createByteStream(1, (byte) 0);
-
- multiPath = new Polyline();
- multiPathImpl = (MultiPathImpl) multiPath._getImpl();
-
- int pointCount;
-
- if (bMultiLineString) {
- pointCount = multiLineStringText_(zs, ms, position, paths,
- path_flags, coordinateArray);
- } else {
- pointCount = lineStringText_(false, zs, ms, position, paths,
- path_flags, coordinateArray);
+ 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();
+ }
}
- if (pointCount != 0) {
- assert (2 * pointCount == position.size());
- multiPathImpl.setAttributeStreamRef(
- VertexDescription.Semantics.POSITION, position);
- multiPathImpl.setPathStreamRef(paths);
- multiPathImpl.setPathFlagsStreamRef(path_flags);
+ 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 (zs != null) {
- multiPathImpl.setAttributeStreamRef(
- VertexDescription.Semantics.Z, zs);
+ if (current_token == JsonReader.Token.VALUE_NUMBER_INT) {
+ return true;
}
- if (ms != null) {
- multiPathImpl.setAttributeStreamRef(
- VertexDescription.Semantics.M, ms);
+ if (current_token == JsonReader.Token.VALUE_NULL
+ || (current_token == JsonReader.Token.VALUE_STRING && json_iterator
+ .currentString().equals("NaN"))) {
+ return true;
}
- multiPathImpl.notifyModified(MultiPathImpl.DirtyFlags.DirtyAll);
+ return false;
}
- return multiPath;
- }
+ //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");
+ }
- private static Geometry multiPointTaggedText_(int importFlags,
- JSONArray coordinateArray) throws JSONException {
- MultiPoint multiPoint;
- MultiPointImpl multiPointImpl;
- AttributeStreamOfDbl zs = null;
- AttributeStreamOfDbl ms = null;
- AttributeStreamOfDbl position;
+ geometry = new MultiPoint();
+ break;
+ }
+ case LineString: {
+ if (m_num_embeddings > 2) {
+ throw new JsonGeometryException("parsing error");
+ }
- position = (AttributeStreamOfDbl) AttributeStreamBase
- .createDoubleStream(0);
+ geometry = new Polyline();
+ break;
+ }
+ case MultiLineString: {
+ if (m_num_embeddings > 3) {
+ throw new JsonGeometryException("parsing error");
+ }
- multiPoint = new MultiPoint();
- multiPointImpl = (MultiPointImpl) multiPoint._getImpl();
+ geometry = new Polyline();
+ break;
+ }
+ case Polygon: {
+ if (m_num_embeddings > 3) {
+ throw new JsonGeometryException("parsing error");
+ }
- int pointCount = multiPointText_(zs, ms, position, coordinateArray);
+ 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");
+ }
- if (pointCount != 0) {
- assert (2 * pointCount == position.size());
- multiPointImpl.resize(pointCount);
- multiPointImpl.setAttributeStreamRef(
- VertexDescription.Semantics.POSITION, position);
+ geometry = createPolygonFromStreams_();
+ }
- multiPointImpl.notifyModified(MultiPointImpl.DirtyFlags.DirtyAll);
+ return geometry;
}
- return multiPoint;
- }
+ 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));
- private static Geometry pointTaggedText_(int importFlags,
- JSONArray coordinateArray) throws JSONException {
- Point point = new Point();
+ Polygon polygon = new Polygon();
+ MultiPathImpl multi_path_impl = (MultiPathImpl) polygon._getImpl();
- int length = coordinateArray.length();
+ checkPathPointCountsForMultiPath_(true);
+ multi_path_impl.setAttributeStreamRef(Semantics.POSITION,
+ m_position);
- if (length == 0) {
- point.setEmpty();
- return point;
- }
+ if (m_b_has_zs) {
+ assert (m_zs != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.Z, m_zs);
+ }
- point.setXY(getDouble_(coordinateArray, 0),
- getDouble_(coordinateArray, 1));
+ if (m_b_has_ms) {
+ assert (m_ms != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.M, m_ms);
+ }
- return point;
- }
+ 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));
- private static int multiPolygonText_(AttributeStreamOfDbl zs,
- AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
- AttributeStreamOfInt32 paths, AttributeStreamOfInt8 path_flags,
- JSONArray coordinateArray) throws JSONException {
- // At start of MultiPolygonText
+ for (int i = 1; i < m_path_flags.size() - 1; i++) {
+ m_path_flags.setBits(i, (byte) PathFlags.enumClosed);
+ }
+ }
- int totalPointCount = 0;
- int length = coordinateArray.length();
+ multi_path_impl.setPathStreamRef(m_paths);
+ multi_path_impl.setPathFlagsStreamRef(m_path_flags);
+ multi_path_impl
+ .notifyModified(MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
- if (length == 0)
- return totalPointCount;
+ AttributeStreamOfInt8 path_flags_clone = new AttributeStreamOfInt8(
+ m_path_flags);
- for (int current = 0; current < length; current++) {
- JSONArray subArray = coordinateArray.optJSONArray(current);
- if (subArray == null) {
- // Entry should be a JSONArray representing a polygon, but it is
- // not a JSONArray.
- throw new IllegalArgumentException("");
+ 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();
- // At start of PolygonText
-
- totalPointCount = polygonText_(zs, ms, position, paths, path_flags,
- totalPointCount, subArray);
+ return polygon;
}
- return totalPointCount;
- }
+ 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);
- private static int multiLineStringText_(AttributeStreamOfDbl zs,
- AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
- AttributeStreamOfInt32 paths, AttributeStreamOfInt8 path_flags,
- JSONArray coordinateArray) throws JSONException {
- // At start of MultiLineStringText
+ Polyline polyline = new Polyline();
+ MultiPathImpl multi_path_impl = (MultiPathImpl) polyline._getImpl();
- int totalPointCount = 0;
- int length = coordinateArray.length();
+ if (m_paths == null) {
+ m_paths = (AttributeStreamOfInt32) AttributeStreamBase
+ .createIndexStream(0);
+ m_paths.add(0);
+ m_paths.add(m_position.size() / 2);
+ }
- if (length == 0)
- return totalPointCount;
+ checkPathPointCountsForMultiPath_(false);
+ multi_path_impl.setAttributeStreamRef(Semantics.POSITION,
+ m_position);
- for (int current = 0; current < length; current++) {
- JSONArray subArray = coordinateArray.optJSONArray(current);
- if (subArray == null) {
- // Entry should be a JSONArray representing a line string, but
- // it is not a JSONArray.
- throw new IllegalArgumentException("");
+ if (m_b_has_zs) {
+ assert (m_zs != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.Z, m_zs);
}
- // At start of LineStringText
+ if (m_b_has_ms) {
+ assert (m_ms != null);
+ multi_path_impl.setAttributeStreamRef(Semantics.M, m_ms);
+ }
- totalPointCount += lineStringText_(false, zs, ms, position, paths,
- path_flags, subArray);
- }
+ m_path_flags = (AttributeStreamOfInt8) AttributeStreamBase
+ .createByteStream(m_paths.size(), (byte) 0);
- return totalPointCount;
- }
+ multi_path_impl.setPathStreamRef(m_paths);
+ multi_path_impl.setPathFlagsStreamRef(m_path_flags);
+ multi_path_impl
+ .notifyModified(MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
+
+ return polyline;
+ }
- private static int multiPointText_(AttributeStreamOfDbl zs,
- AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
- JSONArray coordinateArray) throws JSONException {
- // At start of MultiPointText
+ private Geometry createMultiPointFromStreams_() {
+ assert (m_position != null);
+ assert (m_paths == null);
+ assert (m_path_flags == null);
- int pointCount = 0;
+ MultiPoint multi_point = new MultiPoint();
+ MultiPointImpl multi_point_impl = (MultiPointImpl) multi_point
+ ._getImpl();
+ multi_point_impl.setAttributeStreamRef(Semantics.POSITION,
+ m_position);
- for (int current = 0; current < coordinateArray.length(); current++) {
- JSONArray subArray = coordinateArray.optJSONArray(current);
- if (subArray == null) {
- // Entry should be a JSONArray representing a point, but it is
- // not a JSONArray.
- throw new IllegalArgumentException("");
+ if (m_b_has_zs) {
+ assert (m_zs != null);
+ multi_point_impl.setAttributeStreamRef(Semantics.Z, m_zs);
}
- pointCount += pointText_(zs, ms, position, subArray);
+ 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;
}
- return pointCount;
- }
-
- private static int polygonText_(AttributeStreamOfDbl zs,
- AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
- AttributeStreamOfInt32 paths, AttributeStreamOfInt8 path_flags,
- int totalPointCount, JSONArray coordinateArray)
- throws JSONException {
- // At start of PolygonText
+ 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
+ }
+ }
- int length = coordinateArray.length();
+ if (guess_adjustment == 0) {
+ return; // all paths are okay
+ }
+ }
- if (length == 0) {
- return totalPointCount;
- }
+ 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;
- boolean bFirstLineString = true;
+ if (m_b_has_zs) {
+ adjusted_zs = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(m_zs.size() - guess_adjustment);
+ }
- for (int current = 0; current < length; current++) {
- JSONArray subArray = coordinateArray.optJSONArray(current);
- if (subArray == null) {
- // Entry should be a JSONArray representing a line string, but
- // it is not a JSONArray.
- throw new IllegalArgumentException("");
+ if (m_b_has_ms) {
+ adjusted_ms = (AttributeStreamOfDbl) AttributeStreamBase
+ .createDoubleStream(m_ms.size() - guess_adjustment);
}
- // At start of LineStringText
+ 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);
+ }
- int pointCount = lineStringText_(true, zs, ms, position, paths,
- path_flags, subArray);
+ m_position = adjusted_position;
+ m_paths = adjusted_paths;
+ m_zs = adjusted_zs;
+ m_ms = adjusted_ms;
+ }
- if (pointCount != 0) {
- if (bFirstLineString) {
- bFirstLineString = false;
- path_flags.setBits(path_flags.size() - 2,
- (byte) PathFlags.enumOGCStartPolygon);
- }
+ 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);
+ }
- path_flags.setBits(path_flags.size() - 2,
- (byte) PathFlags.enumClosed);
- totalPointCount += pointCount;
+ if (m_b_has_ms) {
+ adjusted_ms.insertRange(adjusted_start, m_ms, path_start,
+ count, true, 1, adjusted_start);
}
}
- return totalPointCount;
- }
+ 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");
+ }
- private static int lineStringText_(boolean bRing, AttributeStreamOfDbl zs,
- AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
- AttributeStreamOfInt32 paths, AttributeStreamOfInt8 path_flags,
- JSONArray coordinateArray) throws JSONException {
- // At start of LineStringText
+ SpatialReference spatial_reference = null;
- int pointCount = 0;
- int length = coordinateArray.length();
+ try {
+ spatial_reference = SpatialReference.create(wkid);
+ } catch (Exception e) {
+ }
- if (length == 0)
- return pointCount;
+ return spatial_reference;
+ }
- boolean bStartPath = true;
- double startX = NumberUtils.TheNaN;
- double startY = NumberUtils.TheNaN;
- double startZ = NumberUtils.TheNaN;
- double startM = NumberUtils.TheNaN;
+ if (json_iterator.currentToken() != JsonReader.Token.START_OBJECT) {
+ throw new JsonGeometryException("parsing error");
+ }
- for (int current = 0; current < length; current++) {
- JSONArray subArray = coordinateArray.optJSONArray(current);
- if (subArray == null) {
- // Entry should be a JSONArray representing a single point, but
- // it is not a JSONArray.
- throw new IllegalArgumentException("");
+ // 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();
+ }
}
- // At start of x
+ if ((!b_found_type || !b_found_properties) && !b_found_esriwkt) {
+ throw new JsonGeometryException("parsing error");
+ }
- double x = getDouble_(subArray, 0);
- double y = getDouble_(subArray, 1);
- double z = NumberUtils.TheNaN;
- double m = NumberUtils.TheNaN;
+ 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");
+ }
- boolean bAddPoint = true;
+ if (wkid < 0 && !b_found_esriwkt && !b_found_properties_name) {
+ throw new JsonGeometryException("parsing error");
+ }
- if (bRing && pointCount >= 2 && current == length - 1) {
- // If the last point in the ring is not equal to the start
- // point, then let's add it.
+ SpatialReference spatial_reference = null;
- if ((startX == x || (NumberUtils.isNaN(startX) && NumberUtils
- .isNaN(x)))
- && (startY == y || (NumberUtils.isNaN(startY) && NumberUtils
- .isNaN(y)))) {
- bAddPoint = false;
+ if (wkid > 0) {
+ try {
+ spatial_reference = SpatialReference.create(wkid);
+ } catch (Exception e) {
}
}
- if (bAddPoint) {
- if (bStartPath) {
- bStartPath = false;
- startX = x;
- startY = y;
- startZ = z;
- startM = m;
+ 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) {
}
-
- pointCount++;
- addToStreams_(zs, ms, position, x, y, z, m);
}
- }
- if (pointCount == 1) {
- pointCount++;
- addToStreams_(zs, ms, position, startX, startY, startZ, startM);
+ return spatial_reference;
}
- paths.add(position.size() / 2);
- path_flags.add((byte) 0);
+ // 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;
+ }
- return pointCount;
- }
+ if (json_iterator.currentToken() != JsonReader.Token.VALUE_STRING) {
+ throw new JsonGeometryException("parsing error");
+ }
- private static int pointText_(AttributeStreamOfDbl zs,
- AttributeStreamOfDbl ms, AttributeStreamOfDbl position,
- JSONArray coordinateArray) throws JSONException {
- // At start of PointText
+ 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");
+ }
- int length = coordinateArray.length();
+ SpatialReference spatial_reference = SpatialReference.create(wkid);
- if (length == 0)
- return 0;
+ return spatial_reference;
+ }
- // At start of x
+ private static String getCrsIdentifier_(JsonReader json_iterator)
+ throws JsonGeometryException {
+ JsonReader.Token current_token = json_iterator.nextToken();
- double x = getDouble_(coordinateArray, 0);
- double y = getDouble_(coordinateArray, 1);
- double z = NumberUtils.TheNaN;
- double m = NumberUtils.TheNaN;
+ if (current_token != JsonReader.Token.VALUE_STRING) {
+ throw new JsonGeometryException("parsing error");
+ }
- addToStreams_(zs, ms, position, x, y, z, m);
+ return json_iterator.currentString();
+ }
- return 1;
}
- private static void addToStreams_(AttributeStreamOfDbl zs,
- AttributeStreamOfDbl ms, AttributeStreamOfDbl position, double x,
- double y, double z, double m) {
- position.add(x);
- position.add(y);
-
- if (zs != null)
- zs.add(z);
-
- if (ms != null)
- ms.add(m);
+ @Override
+ public MapOGCStructure executeOGC(int import_flags, String geoJsonString,
+ ProgressTracker progress_tracker) throws JsonGeometryException {
+ return executeOGC(import_flags, JsonParserReader.createFromString(geoJsonString),
+ progress_tracker);
}
-
- private static double getDouble_(JSONArray coordinateArray, int index)
- throws JSONException {
- if (index < 0 || index >= coordinateArray.length()) {
- throw new IllegalArgumentException("");
- }
-
- if (coordinateArray.isNull(index)) {
- return NumberUtils.TheNaN;
- }
-
- if (coordinateArray.optDouble(index, NumberUtils.TheNaN) != NumberUtils.TheNaN) {
- return coordinateArray.getDouble(index);
- }
-
- throw new IllegalArgumentException("");
+
+ 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/main/java/com/esri/core/geometry/OperatorImportFromJson.java b/src/main/java/com/esri/core/geometry/OperatorImportFromJson.java
index c05438eb..93f30da5 100644
--- a/src/main/java/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,15 +24,6 @@
package com.esri.core.geometry;
-import java.io.IOException;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.json.JSONObject;
-import org.json.JSONException;
-
-import com.esri.core.geometry.Operator.Type;
-
/**
*Import from JSON format.
*/
@@ -48,29 +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;
-
- /**
- *Performs the ImportFromJson operation on a JSONObject
- *@return Returns a MapGeometry.
- */
- public abstract MapGeometry execute(Geometry.Type type, JSONObject jsonObject)
- throws JSONException, IOException;
-
+ public abstract MapGeometry execute(Geometry.Type type, String string);
public static OperatorImportFromJson local() {
return (OperatorImportFromJson) OperatorFactoryLocal.getInstance()
diff --git a/src/main/java/com/esri/core/geometry/OperatorImportFromJsonCursor.java b/src/main/java/com/esri/core/geometry/OperatorImportFromJsonCursor.java
index cc56169b..2971f441 100644
--- a/src/main/java/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,18 +26,15 @@
import com.esri.core.geometry.MultiVertexGeometryImpl.DirtyFlags;
import com.esri.core.geometry.VertexDescription.Semantics;
-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();
@@ -53,10 +50,10 @@ 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, new JsonParserReader(jsonParser));
+ return importFromJsonParser(m_type, jsonParser);
}
return null;
}
@@ -108,26 +105,26 @@ static MapGeometry importFromJsonParser(int gt, JsonReader parser) {
Geometry geometry = null;
SpatialReference spatial_reference = null;
- while (parser.nextToken() != JsonToken.END_OBJECT) {
+ while (parser.nextToken() != JsonReader.Token.END_OBJECT) {
String name = parser.currentString();
parser.nextToken();
if (!bFoundSpatial_reference && name.equals("spatialReference")) {
bFoundSpatial_reference = true;
- if (parser.currentToken() == JsonToken.START_OBJECT) {
+ if (parser.currentToken() == JsonReader.Token.START_OBJECT) {
spatial_reference = SpatialReference.fromJson(parser);
} else {
- if (parser.currentToken() != 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.currentToken() == JsonToken.VALUE_TRUE);
+ bHasZ = (parser.currentToken() == JsonReader.Token.VALUE_TRUE);
} else if (!bFoundHasM && name.equals("hasM")) {
bFoundHasM = true;
- bHasM = (parser.currentToken() == JsonToken.VALUE_TRUE);
+ bHasM = (parser.currentToken() == JsonReader.Token.VALUE_TRUE);
} else if (!bFoundPolygon
&& name.equals("rings")
&& (gt == Geometry.GeometryType.Unknown || gt == Geometry.GeometryType.Polygon)) {
@@ -271,7 +268,6 @@ static MapGeometry importFromJsonParser(int gt, JsonReader parser) {
mp = new MapGeometry(geometry, spatial_reference);
} catch (Exception e) {
- e.printStackTrace();
return null;
}
@@ -309,15 +305,13 @@ public static MapGeometry fromJsonToMultiPoint(JsonReader parser)
return importFromJsonParser(Geometry.GeometryType.MultiPoint, parser);
}
- private static void windup(JsonReader parser) throws Exception,
- JsonParseException {
+ private static void windup(JsonReader parser) {
parser.skipChildren();
}
- private static double readDouble(JsonReader parser) throws Exception,
- JsonParseException {
- if (parser.currentToken() == JsonToken.VALUE_NULL
- || parser.currentToken() == JsonToken.VALUE_STRING
+ 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
@@ -326,7 +320,7 @@ private static double readDouble(JsonReader parser) throws Exception,
private static Geometry importFromJsonMultiPoint(JsonReader parser,
AttributeStreamOfDbl as, AttributeStreamOfDbl bs) throws Exception {
- if (parser.currentToken() != JsonToken.START_ARRAY)
+ if (parser.currentToken() != JsonReader.Token.START_ARRAY)
throw new GeometryException(
"failed to parse multipoint: array of vertices is expected");
@@ -341,13 +335,13 @@ private static Geometry importFromJsonMultiPoint(JsonReader parser,
// At start of rings
int sz;
double[] buf = new double[4];
- while (parser.nextToken() != JsonToken.END_ARRAY) {
- if (parser.currentToken() != 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);
}
@@ -409,7 +403,7 @@ else if (c < 16)
private static Geometry importFromJsonMultiPath(boolean b_polygon,
JsonReader parser, AttributeStreamOfDbl as, AttributeStreamOfDbl bs)
throws Exception {
- if (parser.currentToken() != JsonToken.START_ARRAY)
+ if (parser.currentToken() != JsonReader.Token.START_ARRAY)
throw new GeometryException(
"failed to parse multipath: array of array of vertices is expected");
@@ -437,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.currentToken() != 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");
@@ -448,13 +442,13 @@ private static Geometry importFromJsonMultiPath(boolean b_polygon,
int szstart = 0;
parser.nextToken();
- while (parser.currentToken() != JsonToken.END_ARRAY) {
- if (parser.currentToken() != 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);
}
@@ -523,7 +517,7 @@ else if (c < 16)
point_count++;
pathPointCount++;
} while (pathPointCount < requiredSize
- && parser.currentToken() == 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
index f92842fb..55d94171 100644
--- a/src/main/java/com/esri/core/geometry/OperatorImportFromJsonLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorImportFromJsonLocal.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,46 +23,20 @@
*/
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.json.JSONObject;
-import org.json.JSONException;
-
-import com.esri.core.geometry.ogc.OGCGeometry;
-
class OperatorImportFromJsonLocal extends OperatorImportFromJson {
@Override
public MapGeometryCursor execute(Geometry.Type type,
- JsonParserCursor jsonParserCursor) {
+ JsonReaderCursor jsonParserCursor) {
return new OperatorImportFromJsonCursor(type.value(), jsonParserCursor);
}
@Override
- public MapGeometry execute(Geometry.Type type, JsonParser jsonParser) {
- SimpleJsonParserCursor jsonParserCursor = new SimpleJsonParserCursor(
- jsonParser);
- OperatorImportFromJsonCursor cursor = new OperatorImportFromJsonCursor(
- type.value(), jsonParserCursor);
- return cursor.next();
+ public MapGeometry execute(Geometry.Type type, JsonReader jsonParser) {
+ return OperatorImportFromJsonCursor.importFromJsonParser(type.value(), jsonParser);
}
@Override
- public MapGeometry execute(Geometry.Type type, String string)
- throws JsonParseException, IOException {
- JsonFactory factory = new JsonFactory();
- JsonParser jsonParserPt = factory.createJsonParser(string);
- jsonParserPt.nextToken();
- return execute(type, jsonParserPt);
+ public MapGeometry execute(Geometry.Type type, String string) {
+ return execute(type, JsonParserReader.createFromString(string));
}
- @Override
- public MapGeometry execute(Geometry.Type type, JSONObject jsonObject)
- throws JSONException, IOException {
- if (jsonObject == null)
- return null;
-
- return OperatorImportFromJsonCursor.importFromJsonParser(type.value(), new JsonValueReader(jsonObject));
- }
}
diff --git a/src/main/java/com/esri/core/geometry/OperatorImportFromWkb.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWkb.java
index 9550e4cf..a80e3bd9 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorImportFromWkbLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWkbLocal.java
index 6fa9c01a..1fa9685c 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorImportFromWkt.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWkt.java
index b64c70ac..60b0460d 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorImportFromWktLocal.java b/src/main/java/com/esri/core/geometry/OperatorImportFromWktLocal.java
index 3a9bb232..3b6a74f0 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorInternalRelationUtils.java b/src/main/java/com/esri/core/geometry/OperatorInternalRelationUtils.java
index 7f78b59d..5c61ad20 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorIntersection.java b/src/main/java/com/esri/core/geometry/OperatorIntersection.java
index c1230446..5afc6e37 100644
--- a/src/main/java/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.
@@ -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,7 +81,7 @@ 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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorIntersectionCursor.java b/src/main/java/com/esri/core/geometry/OperatorIntersectionCursor.java
index 7706d83e..edcf0313 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorIntersectionLocal.java b/src/main/java/com/esri/core/geometry/OperatorIntersectionLocal.java
index bb13dcf3..71d2d9e6 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorIntersects.java b/src/main/java/com/esri/core/geometry/OperatorIntersects.java
index d7984fa8..ace6c277 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorIntersectsLocal.java b/src/main/java/com/esri/core/geometry/OperatorIntersectsLocal.java
index 5a492095..1abefd6a 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorOffset.java b/src/main/java/com/esri/core/geometry/OperatorOffset.java
index 910ccd8a..bdcf5005 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorOffsetCursor.java b/src/main/java/com/esri/core/geometry/OperatorOffsetCursor.java
index 5f27c667..76f1f982 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorOffsetLocal.java b/src/main/java/com/esri/core/geometry/OperatorOffsetLocal.java
index 7006b42d..06c7f3c6 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorOverlaps.java b/src/main/java/com/esri/core/geometry/OperatorOverlaps.java
index d1a362b4..c7b3b207 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorOverlapsLocal.java b/src/main/java/com/esri/core/geometry/OperatorOverlapsLocal.java
index f767cafd..f9114687 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorProject.java b/src/main/java/com/esri/core/geometry/OperatorProject.java
index da2a1712..db74ae12 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorProjectLocal.java b/src/main/java/com/esri/core/geometry/OperatorProjectLocal.java
index 78598ca6..ae753433 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorProximity2D.java b/src/main/java/com/esri/core/geometry/OperatorProximity2D.java
index 80327e18..7449fc95 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorProximity2DLocal.java b/src/main/java/com/esri/core/geometry/OperatorProximity2DLocal.java
index 363c29a4..d62f514d 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorRelate.java b/src/main/java/com/esri/core/geometry/OperatorRelate.java
index b1e435bf..d5542990 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorRelateLocal.java b/src/main/java/com/esri/core/geometry/OperatorRelateLocal.java
index c83fbee1..88af8ad0 100644
--- a/src/main/java/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
index 3aa5ed8e..b25d66e0 100644
--- a/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensify.java
+++ b/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensify.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 Type getType() {
* @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 < 1, but simply passes them along).
+ * @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.
*/
@@ -58,7 +58,7 @@ public Type getType() {
* @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 < 1, but simply passes them along).
+ * @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.
*/
diff --git a/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensifyLocal.java b/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensifyLocal.java
index 01bcf3a7..68fd0a5c 100644
--- a/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensifyLocal.java
+++ b/src/main/java/com/esri/core/geometry/OperatorShapePreservingDensifyLocal.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/OperatorSimpleRelation.java b/src/main/java/com/esri/core/geometry/OperatorSimpleRelation.java
index f4afeff7..1a08cf6d 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorSimplify.java b/src/main/java/com/esri/core/geometry/OperatorSimplify.java
index 0e14b2f9..3e9beca9 100644
--- a/src/main/java/com/esri/core/geometry/OperatorSimplify.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplify.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/OperatorSimplifyCursor.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyCursor.java
index 4be821a8..19c920df 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorSimplifyCursorOGC.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyCursorOGC.java
index 277724d6..15e726af 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorSimplifyLocal.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocal.java
index 6cb16dc1..4edc081e 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorSimplifyLocalHelper.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocalHelper.java
index 791f394a..2513693e 100644
--- a/src/main/java/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.
@@ -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
@@ -1643,6 +1632,16 @@ 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);
@@ -1650,12 +1649,12 @@ MultiVertexGeometry simplifyPlanar_() {
assert (m_knownSimpleResult != GeometryXSimple.Strong);
if (m_knownSimpleResult != GeometryXSimple.Weak) {
CrackAndCluster.execute(m_editShape, m_toleranceSimplify,
- m_progressTracker);
+ m_progressTracker, true);
}
if (m_geometry.getType().equals(Geometry.Type.Polygon)) {
Simplificator.execute(m_editShape, m_editShape.getFirstGeometry(),
- m_knownSimpleResult, false);
+ m_knownSimpleResult, false, m_progressTracker);
}
}
@@ -1665,8 +1664,10 @@ MultiVertexGeometry simplifyPlanar_() {
// 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,
@@ -1940,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;
}
diff --git a/src/main/java/com/esri/core/geometry/OperatorSimplifyLocalOGC.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyLocalOGC.java
index aa9c5a9f..6c725abb 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorSimplifyOGC.java b/src/main/java/com/esri/core/geometry/OperatorSimplifyOGC.java
index d433f0c7..c04ba0c4 100644
--- a/src/main/java/com/esri/core/geometry/OperatorSimplifyOGC.java
+++ b/src/main/java/com/esri/core/geometry/OperatorSimplifyOGC.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/OperatorSymmetricDifference.java b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifference.java
index bb914e77..ea84ce0c 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceCursor.java
index 92450ce3..3d265593 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java b/src/main/java/com/esri/core/geometry/OperatorSymmetricDifferenceLocal.java
index e5de43db..e505a8dd 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorTouches.java b/src/main/java/com/esri/core/geometry/OperatorTouches.java
index a98de285..6ae67f38 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorTouchesLocal.java b/src/main/java/com/esri/core/geometry/OperatorTouchesLocal.java
index f18f3541..48d32d89 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorUnion.java b/src/main/java/com/esri/core/geometry/OperatorUnion.java
index 69340bd2..8a0a8601 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/OperatorUnionCursor.java b/src/main/java/com/esri/core/geometry/OperatorUnionCursor.java
index 53164ef2..0ddd88b8 100644
--- a/src/main/java/com/esri/core/geometry/OperatorUnionCursor.java
+++ b/src/main/java/com/esri/core/geometry/OperatorUnionCursor.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.
@@ -183,26 +183,23 @@ private boolean step_(){
}
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;
- }
- }
- }
- }
+ 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;
diff --git a/src/main/java/com/esri/core/geometry/OperatorUnionLocal.java b/src/main/java/com/esri/core/geometry/OperatorUnionLocal.java
index e3cf5ea7..1b723282 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorWithin.java b/src/main/java/com/esri/core/geometry/OperatorWithin.java
index 9032718f..00a0c15f 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/OperatorWithinLocal.java b/src/main/java/com/esri/core/geometry/OperatorWithinLocal.java
index 9958ff90..a370a8fe 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/PathFlags.java b/src/main/java/com/esri/core/geometry/PathFlags.java
index b163559e..1fa09c35 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/PeDouble.java b/src/main/java/com/esri/core/geometry/PeDouble.java
index 90bf9abf..fd33af49 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/PlaneSweepCrackerHelper.java b/src/main/java/com/esri/core/geometry/PlaneSweepCrackerHelper.java
index ab23f7c1..c84b4724 100644
--- a/src/main/java/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.
@@ -68,7 +68,11 @@ boolean sweep(EditShape shape, double tolerance) {
b_cracked |= sweepImpl_();
}
- m_shape.removeUserIndex(m_vertex_cluster_index);
+ 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;
}
@@ -82,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;
}
@@ -758,22 +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);
- seg.getStartXY(pt_2);
- int clusterStart = getEdgeCluster(edge, 0);
- getClusterXY(clusterStart, pt_1);
- if (!pt_1.isEqual(pt_2)) {
- int res1 = pt_1.compare(m_sweep_point);
- int res2 = pt_2.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
+ 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
@@ -781,18 +802,37 @@ void processSplitHelper1_(int index, int edge,
m_modified_clusters.add(clusterStart);
}
- seg = intersector.getResultSegment(index, count - 1);
- seg.getEndXY(pt_2);
- int clusterEnd = getEdgeCluster(edge, 1);
- getClusterXY(clusterEnd, pt_1);
- if (!pt_1.isEqual(pt_2)) {
- int res1 = pt_1.compare(m_sweep_point);
- int res2 = pt_2.compare(m_sweep_point);
- if (res1 * res2 < 0) {
- m_complications = true;// point is not yet have been processed
- // but moved before the sweep point.
+ 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();
+ 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);
@@ -1172,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);
diff --git a/src/main/java/com/esri/core/geometry/Point.java b/src/main/java/com/esri/core/geometry/Point.java
index 11459be5..cc5b7042 100644
--- a/src/main/java/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.
@@ -28,29 +28,35 @@
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();
}
/**
@@ -67,6 +73,7 @@ public Point(double x, double y) {
m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
setXY(x, y);
}
+
public Point(Point2D pt) {
m_description = VertexDescriptionDesignerImpl.getDefaultDescriptor2D();
setXY(pt);
@@ -90,19 +97,14 @@ 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.
*/
public final Point2D getXY() {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation should not be performed on an empty geometry.");
-
Point2D pt = new Point2D();
- pt.setCoords(m_attributes[0], m_attributes[1]);
+ pt.setCoords(m_x, m_y);
return pt;
}
@@ -110,11 +112,7 @@ public final Point2D getXY() {
* Returns XY coordinates of this point.
*/
public final void getXY(Point2D pt) {
- if (isEmptyImpl())
- throw new GeometryException(
- "This operation should not be performed on an empty geometry.");
-
- pt.setCoords(m_attributes[0], m_attributes[1]);
+ pt.setCoords(m_x, m_y);
}
/**
@@ -129,18 +127,11 @@ public final 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;
}
@@ -151,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;
}
/**
@@ -195,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;
}
/**
@@ -216,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);
}
/**
@@ -281,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();
@@ -292,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);
}
@@ -309,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);
}
/**
@@ -339,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();
@@ -349,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;
}
@@ -370,65 +340,79 @@ public int getDimension() {
return 0;
}
+ @Override
+ public long estimateMemorySize()
+ {
+ return SIZE_OF_POINT + estimateMemorySize(m_attributes);
+ }
+
@Override
public void setEmpty() {
_touch();
- if (m_attributes != null) {
- m_attributes[0] = NumberUtils.NaN();
- m_attributes[1] = NumberUtils.NaN();
- }
+ _setToDefault();
}
@Override
protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
- if (m_attributes == null) {
- m_description = newDescription;
- return;
- }
-
int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);
- double[] newAttributes = new double[newDescription._getTotalComponents()];
-
- int j = 0;
- for (int i = 0, 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++)
+ 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)
{
- newAttributes[j] = d;
- j++;
+ 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);
- for (int ord = 0; ord < nords; ord++)
- {
- newAttributes[j] = m_attributes[offset];
- j++;
- offset++;
+ 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;
}
-
- 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
@@ -442,7 +426,7 @@ public void applyTransformation(Transformation2D transform) {
}
@Override
- void applyTransformation(Transformation3D transform) {
+ public void applyTransformation(Transformation3D transform) {
if (isEmptyImpl())
return;
@@ -455,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
@@ -483,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
@@ -516,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
@@ -539,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) {
- if (count > 0)
- System.arraycopy(src, 0, dst, 0, count);
- }
-
/**
* Set the X and Y coordinate of the point.
*
@@ -565,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;
}
/**
@@ -589,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;
}
@@ -610,17 +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 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
index 5525626b..95a46c66 100644
--- a/src/main/java/com/esri/core/geometry/Point2D.java
+++ b/src/main/java/com/esri/core/geometry/Point2D.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.
@@ -48,6 +48,10 @@ public Point2D(double x, double y) {
this.y = y;
}
+ public Point2D(Point2D other) {
+ setCoords(other);
+ }
+
public static Point2D construct(double x, double y) {
return new Point2D(x, y);
}
@@ -90,6 +94,12 @@ public boolean equals(Object 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;
@@ -122,20 +132,29 @@ public void negate(Point2D other) {
}
public void interpolate(Point2D other, double alpha) {
- x = x * (1.0 - alpha) + other.x * alpha;
- y = y * (1.0 - alpha) + other.y * alpha;
+ MathUtils.lerp(this, other, alpha, this);
}
public void interpolate(Point2D p1, Point2D p2, double alpha) {
- x = p1.x * (1.0 - alpha) + p2.x * alpha;
- y = p1.y * (1.0 - alpha) + p2.y * 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;
@@ -152,12 +171,19 @@ public void scale(double f) {
}
/**
- * Compares two vertices lexicographicaly.
+ * 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();
@@ -266,7 +292,7 @@ void _setNan() {
}
boolean _isNan() {
- return NumberUtils.isNaN(x);
+ return NumberUtils.isNaN(x) || NumberUtils.isNaN(y);
}
// calculates which quarter of xy plane the vector lies in. First quater is
@@ -415,7 +441,7 @@ public boolean isNaN() {
}
/**
- * Calculates the orientation of the triangle formed by p->q->r. Returns 1
+ * 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.
*/
@@ -475,9 +501,264 @@ public static int orientationRobust(Point2D p, Point2D q, Point2D r) {
return det_mp.signum();
}
- @Override
- public int hashCode() {
- return NumberUtils.hash(NumberUtils.hash(x), y);
+ 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
index 5f509019..71cbfdba 100644
--- a/src/main/java/com/esri/core/geometry/Point3D.java
+++ b/src/main/java/com/esri/core/geometry/Point3D.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,11 +42,17 @@ public final class Point3D implements Serializable {
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.x = x;
- pt.y = y;
- pt.z = z;
+ pt.setCoords(x, y, z);
return pt;
}
@@ -56,6 +62,10 @@ public void setCoords(double x, double y, double z) {
this.z = z;
}
+ public void setCoords(Point3D other) {
+ setCoords(other.x, other.y, other.z);
+ }
+
public void setZero() {
x = 0.0;
y = 0.0;
@@ -64,38 +74,89 @@ public void setZero() {
public void normalize() {
double len = length();
- if (len != 0)
- return;
+ if (len == 0) {
+ x = 1.0;
+ y = 0.0;
+ z = 0.0;
+ } else {
+ x /= len;
+ y /= len;
+ z /= len;
+ }
+ }
- 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 Point3D(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.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 Point3D sub(Point3D other) {
- return new Point3D(x - other.x, y - other.y, z - other.z);
+ public void scale(double f, Point3D other) {
+ x = f * other.x;
+ y = f * other.y;
+ z = f * other.z;
}
- public Point3D mul(double factor) {
- return new Point3D(x * factor, y * factor, z * factor);
+ 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);
+ 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/main/java/com/esri/core/geometry/PointInPolygonHelper.java b/src/main/java/com/esri/core/geometry/PointInPolygonHelper.java
index 0cda4401..801b2b81 100644
--- a/src/main/java/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);
}
@@ -280,28 +280,61 @@ else if (hit == RasterizedGeometry2D.HitType.Outside)
}
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,
@@ -354,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/main/java/com/esri/core/geometry/Polygon.java b/src/main/java/com/esri/core/geometry/Polygon.java
index 8faea700..949a3797 100644
--- a/src/main/java/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.
*
@@ -138,5 +144,42 @@ public 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/main/java/com/esri/core/geometry/PolygonUtils.java b/src/main/java/com/esri/core/geometry/PolygonUtils.java
index 005446d0..d56f2220 100644
--- a/src/main/java/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,36 +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(MultiPath polygon, int iRing1,
- int iRing2, double tolerance) {
- 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;// 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 GeometryException.GeometryInternalError();
- if (res == 1 /* (int)PiPResult.PiPInside */)
- return true;
-
- return false;
- }
-
private static void _testPointsInEnvelope2D(Envelope2D env2D,
Point2D[] inputPoints, int count, double tolerance,
PiPResult[] testResults) {
diff --git a/src/main/java/com/esri/core/geometry/Polyline.java b/src/main/java/com/esri/core/geometry/Polyline.java
index 2124a0f4..9f45d7ea 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/PolylinePath.java b/src/main/java/com/esri/core/geometry/PolylinePath.java
deleted file mode 100644
index b3c06dc8..00000000
--- a/src/main/java/com/esri/core/geometry/PolylinePath.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- 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.util.Comparator;
-
-class PolylinePath {
- Point2D m_fromPoint;
- Point2D m_toPoint;
- double m_fromDist; // from lower left corner; -1.0 if point is not on
- // clipping bounday
- double m_toDist; // from lower left corner; -1.0 if point is not on clipping
- // bounday
- int m_path; // from polyline
- boolean m_used;
-
- public PolylinePath() {
- }
-
- public PolylinePath(Point2D fromPoint, Point2D toPoint, double fromDist,
- double toDist, int path) {
- m_fromPoint = fromPoint;
- m_toPoint = toPoint;
- m_fromDist = fromDist;
- m_toDist = toDist;
- m_path = path;
- m_used = false;
- }
-
- void setValues(Point2D fromPoint, Point2D toPoint, double fromDist,
- double toDist, int path) {
- m_fromPoint = fromPoint;
- m_toPoint = toPoint;
- m_fromDist = fromDist;
- m_toDist = toDist;
- m_path = path;
- m_used = false;
- }
-
- // to be used in Use SORTARRAY
-
-}
-
-class PolylinePathComparator implements Comparator {
- @Override
- public int compare(PolylinePath v1, PolylinePath v2) {
- if ((v1).m_fromDist < (v2).m_fromDist)
- return -1;
- else if ((v1).m_fromDist > (v2).m_fromDist)
- return 1;
- else
- return 0;
- }
-
-}
diff --git a/src/main/java/com/esri/core/geometry/ProgressTracker.java b/src/main/java/com/esri/core/geometry/ProgressTracker.java
index d4153375..09933688 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/ProjectionTransformation.java b/src/main/java/com/esri/core/geometry/ProjectionTransformation.java
index 4f2aedde..858bc03c 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/Proximity2DResult.java b/src/main/java/com/esri/core/geometry/Proximity2DResult.java
index 04ac528d..0e1efe71 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/Proximity2DResultComparator.java b/src/main/java/com/esri/core/geometry/Proximity2DResultComparator.java
index 1be0cfbb..0404aa80 100644
--- a/src/main/java/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
index 59f976d5..0b4a4945 100644
--- a/src/main/java/com/esri/core/geometry/QuadTree.java
+++ b/src/main/java/com/esri/core/geometry/QuadTree.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,27 +25,38 @@
package com.esri.core.geometry;
-public class QuadTree {
+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 Quad_tree. If the
+ * 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 Envelope_2D bounding the Geometry.
- * \param query The Geometry used for the query. \param tolerance The
- * tolerance used for the intersection tests.
+ * 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) {
- m_impl.resetIterator(query, 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 Quad_tree 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
+ * 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) {
- m_impl.resetIterator(query, tolerance);
+ if (!m_b_sorted)
+ ((QuadTreeImpl.QuadTreeIteratorImpl) m_impl).resetIterator(query, tolerance);
+ else
+ ((QuadTreeImpl.QuadTreeSortedIteratorImpl) m_impl).resetIterator(query, tolerance);
}
/**
@@ -53,7 +64,10 @@ public void resetIterator(Envelope2D query, double tolerance) {
* Element_handle.
*/
public int next() {
- return m_impl.next();
+ if (!m_b_sorted)
+ return ((QuadTreeImpl.QuadTreeIteratorImpl) m_impl).next();
+ else
+ return ((QuadTreeImpl.QuadTreeSortedIteratorImpl) m_impl).next();
}
/**
@@ -63,136 +77,260 @@ Object getImpl_() {
return m_impl;
}
- // Creates an iterator on the input Quad_tree_impl. The query will be
- // the Envelope_2D bounding the input Geometry.
- private QuadTreeIterator(Object obj) {
- m_impl = (QuadTreeImpl.QuadTreeIteratorImpl) obj;
+ // 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 QuadTreeImpl.QuadTreeIteratorImpl m_impl;
- };
+ private Object m_impl;
+ private boolean m_b_sorted;
+ }
/**
- * Creates a Quad_tree with the root having the extent of the input
- * Envelope_2D, and height of the input height, where the root starts at
- * height 0. Note that the height cannot be larger than 16 if on a 32 bit
- * platform and 32 if on a 64 bit platform. \param extent The extent of the
- * Quad_tree. \param height The max height of the Quad_tree.
+ * 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);
}
/**
- * Inserts the element and bounding_box into the Quad_tree. Note that a copy
+ * 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 Quad_tree. 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
+ * 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 bounding_box) {
- return m_impl.insert(element, bounding_box);
+ public int insert(int element, Envelope2D boundingBox) {
+ return m_impl.insert(element, boundingBox);
}
/**
- * Inserts the element and bounding_box into the Quad_tree at the given
+ * 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 Quad_tree.
+ * 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
+ * \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 bounding_box, int hint_index) {
- return m_impl.insert(element, bounding_box, hint_index);
+ 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 Quad_tree. \param
- * element_handle The handle corresponding to the element and bounding_box
+ * 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 element_handle) {
- m_impl.removeElement(element_handle);
+ 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 element at the given element_handle. \param element_handle
- * The handle corresponding to the element to be retrieved.
+ * 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 getElement(int element_handle) {
- return m_impl.getElement(element_handle);
+ 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 quad_handle) {
- return m_impl.getHeight(quad_handle);
+ public int getHeight(int quadHandle) {
+ return m_impl.getHeight(quadHandle);
}
/**
- * Returns the extent of the quad at the given quad_handle. \param
- * quad_handle The handle corresponding to the quad.
+ * Returns the max height the quad tree can grow to.
*/
- public Envelope2D getExtent(int quad_handle) {
- return m_impl.getExtent(quad_handle);
+ 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 element_handle) {
- return m_impl.getQuad(element_handle);
+ public int getQuad(int elementHandle) {
+ return m_impl.getQuad(elementHandle);
}
/**
- * Returns the number of elements in the Quad_tree.
+ * Returns the number of elements in the QuadTree.
*/
public int getElementCount() {
return m_impl.getElementCount();
}
/**
- * Gets an iterator on the Quad_tree. The query will be the Envelope_2D that
+ * 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
- * Quad_tree but with a new query, use the reset_iterator function on the
- * Quad_tree_iterator. \param query The Geometry used for the query. If the
+ * 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 Envelope_2D bounding the Geometry. \param tolerance
- * The tolerance used for the intersection tests.
+ * 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);
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, false);
}
/**
- * Gets an iterator on the Quad_tree using the input Envelope_2D as the
- * query. To reuse the existing iterator on the same Quad_tree but with a
- * new query, use the reset_iterator function on the Quad_tree_iterator.
- * \param query The Envelope_2D used for the query. \param tolerance The
- * tolerance used for the intersection tests.
+ * 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);
+ QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator(query, tolerance);
+ return new QuadTreeIterator(iterator, false);
}
/**
- * Gets an iterator on the Quad_tree.
+ * Gets an iterator on the QuadTree.
*/
public QuadTreeIterator getIterator() {
QuadTreeImpl.QuadTreeIteratorImpl iterator = m_impl.getIterator();
- return new QuadTreeIterator(iterator);
+ 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);
+ }
}
/**
diff --git a/src/main/java/com/esri/core/geometry/QuadTreeImpl.java b/src/main/java/com/esri/core/geometry/QuadTreeImpl.java
index 84c16f67..e9234bb5 100644
--- a/src/main/java/com/esri/core/geometry/QuadTreeImpl.java
+++ b/src/main/java/com/esri/core/geometry/QuadTreeImpl.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,9 +23,19 @@
*/
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;
-class QuadTreeImpl {
+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
@@ -42,7 +52,7 @@ void resetIterator(Geometry query, double tolerance) {
query.queryLooseEnvelope2D(m_query_box);
m_query_box.inflate(tolerance, tolerance);
- if (m_query_box.isIntersecting(m_quad_tree.m_extent)) {
+ 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);
@@ -57,8 +67,7 @@ void resetIterator(Geometry query, double tolerance) {
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
- .getFirstElement_(m_quad_tree.m_root);
+ m_next_element_handle = m_quad_tree.get_first_element_(m_quad_tree.m_root);
} else
m_next_element_handle = -1;
}
@@ -77,11 +86,10 @@ void resetIterator(Envelope2D query, double tolerance) {
m_query_box.inflate(tolerance, tolerance);
m_tolerance = NumberUtils.NaN(); // we don't need it
- if (m_query_box.isIntersecting(m_quad_tree.m_extent)) {
+ 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
- .getFirstElement_(m_quad_tree.m_root);
+ 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;
@@ -104,7 +112,7 @@ int next() {
Envelope2D extent_inf = null;
Envelope2D[] child_extents = null;
- if (m_b_linear) {// Should this memory be cached for reuse?
+ if (m_b_linear) {
start = new Point2D();
end = new Point2D();
extent_inf = new Envelope2D();
@@ -113,10 +121,8 @@ int next() {
boolean b_found_hit = false;
while (!b_found_hit) {
while (m_current_element_handle != -1) {
- int current_box_handle = m_quad_tree
- .getBoxHandle_(m_current_element_handle);
- bounding_box = m_quad_tree
- .getBoundingBox_(current_box_handle);
+ 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) {
@@ -136,21 +142,14 @@ int next() {
}
// get next element_handle
- m_current_element_handle = m_quad_tree
- .getNextElement_(m_current_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 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
+ // 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);
-
- double x_mid = 0.5 * (current_extent.xmin + current_extent.xmax);
- double y_mid = 0.5 * (current_extent.ymin + current_extent.ymax);
+ Envelope2D current_extent = m_extents_stack.get(m_extents_stack.size() - 1);
if (child_extents == null) {
child_extents = new Envelope2D[4];
@@ -160,38 +159,30 @@ int next() {
child_extents[3] = new Envelope2D();
}
- setChildExtents_(current_extent, child_extents);
+ 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.getChild_(current_quad,
- quadrant);
-
- if (child_handle != -1
- && m_quad_tree
- .getSubTreeElementCount(child_handle) > 0) {
- if (child_extents[quadrant]
- .isIntersecting(m_query_box)) {
+ 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);
+ 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]);
+ 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]);
+ child_extent.setCoords(child_extents[quadrant]);
m_quads_stack.add(child_handle);
m_extents_stack.add(child_extent);
}
@@ -204,24 +195,20 @@ int next() {
if (m_quads_stack.size() == 0)
return -1;
- m_current_element_handle = m_quad_tree
- .getFirstElement_(m_quads_stack.get(m_quads_stack
- .size() - 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
- .getNextElement_(m_current_element_handle);
+ 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) {
+ 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);
@@ -231,8 +218,7 @@ int next() {
// 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) {
+ 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);
@@ -257,134 +243,346 @@ int next() {
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)
+ 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. Note that the height cannot be larger than 16 if on a 32 bit
- * platform and 32 if on a 64 bit platform. \param extent The extent of the
- * Quad_tree_impl. \param height The max height of the Quad_tree_impl.
+ * 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(11);
- m_element_nodes = new StridedIndexTypeCollection(5);
- m_boxes = new ArrayList(0);
- m_free_boxes = new AttributeStreamOfInt32(0);
+ 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);
}
/**
- * 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.
+ * 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_boxes.clear();
- m_free_boxes.clear(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 int 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.
+ * 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) {
- return insert_(element, bounding_box, 0, m_extent, m_root, false, -1);
+ 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 int corresponding to the element and
- * bounding_box. \param element The element of the Geometry to be inserted.
+ * 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.
+ * \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 = getQuad_(hint_index);
+ quad_handle = get_quad_(hint_index);
int quad_height = getHeight(quad_handle);
Envelope2D quad_extent = getExtent(quad_handle);
- return insert_(element, bounding_box, quad_height, quad_extent,
- quad_handle, false, -1);
+
+ 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.
+ * 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) {
- int quad_handle = getQuad_(element_handle);
- int nextElementHandle = disconnectElementHandle_(element_handle);
- freeElementAndBoxNode_(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;
- for (int q = quad_handle; q != -1; q = getParent_(q)) {
- setSubTreeElementCount_(q, getSubTreeElementCount_(q) - 1);
- assert (getSubTreeElementCount_(q) >= 0);
+ 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.
+ * 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 getElement_(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 height of the quad at the given quad_handle. \param
- * quad_handle The handle corresponding to the quad.
+ * 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 getHeight_(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.
+ * 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);
- int height = getHeight_(quad_handle);
- int morten_number = getMortenNumber_(quad_handle);
- int mask = 3;
+ 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);
- for (int i = 0; i < 2 * height; i += 2) {
- int child = (int) (mask & (morten_number >> i));
+ int sz = quadrants.size();
+ assert (sz == getHeight(quad_handle));
- if (child == 0) {// northeast
+ 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
+ } 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
+ } 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
+ } else {//southeast
quad_extent.xmin = 0.5 * (quad_extent.xmin + quad_extent.xmax);
quad_extent.ymax = 0.5 * (quad_extent.ymin + quad_extent.ymax);
}
@@ -394,26 +592,134 @@ Envelope2D getExtent(int quad_handle) {
}
/**
- * Returns the int of the quad containing the given element_handle. \param
- * element_handle The handle corresponding to the element.
+ * 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 getQuad_(element_handle);
+ return get_quad_(element_handle);
}
/**
* Returns the number of elements in the Quad_tree_impl.
*/
int getElementCount() {
- return getSubTreeElementCount_(m_root);
+ 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.
+ * 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 getSubTreeElementCount_(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;
}
/**
@@ -447,37 +753,74 @@ 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) {
- // We need 2 * height bits for the morten number, which is of type
- // Index_type (more than enough).
- if (height < 0 || 2 * height > 8 * 4)
+ if (height < 0 || height > 127)
throw new IllegalArgumentException("invalid height");
m_height = height;
m_extent.setCoords(extent);
m_root = m_quad_tree_nodes.newElement();
- setSubTreeElementCount_(m_root, 0);
- setLocalElementCount_(m_root, 0);
- setMortenNumber_(m_root, 0);
- setHeight_(m_root, 0);
+ 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) {
+ 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);
+ 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 = getParent_(q))
- setSubTreeElementCount_(q, getSubTreeElementCount_(q) + 1);
+ 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();
@@ -492,9 +835,8 @@ private int insert_(int element, Envelope2D bounding_box, int height,
child_extents[3] = new Envelope2D();
int current_height;
- for (current_height = height; current_height < m_height
- && canPushDown_(current_quad_handle); current_height++) {
- setChildExtents_(current_extent, child_extents);
+ 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;
@@ -502,12 +844,11 @@ private int insert_(int element, Envelope2D bounding_box, int height,
if (child_extents[i].contains(bounding_box)) {
b_contains = true;
- int child_handle = getChild_(current_quad_handle, i);
+ int child_handle = get_child_(current_quad_handle, i);
if (child_handle == -1)
- child_handle = createChild_(current_quad_handle, i);
+ child_handle = create_child_(current_quad_handle, i);
- setSubTreeElementCount_(child_handle,
- getSubTreeElementCount_(child_handle) + 1);
+ 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]);
@@ -519,22 +860,112 @@ private int insert_(int element, Envelope2D bounding_box, int height,
break;
}
- return insertAtQuad_(element, bounding_box, current_height,
- current_extent, current_quad_handle, b_flushing, quad_handle,
- flushed_element_handle);
+ 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 insertAtQuad_(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) {
- // 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
+ 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 = getFirstElement_(current_quad_handle);
- int tail_element_handle = getLastElement_(current_quad_handle);
+ 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) {
@@ -543,295 +974,407 @@ private int insertAtQuad_(int element, Envelope2D bounding_box,
if (current_quad_handle == quad_handle)
return flushed_element_handle;
- disconnectElementHandle_(flushed_element_handle); // Take it out of
- // the incoming
- // quad_handle,
- // and place in
- // current_quad_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 {
- element_handle = createElementAndBoxNode_();
- setElement_(element_handle, element); // insert element at the new
- // tail of the list
- // (next_element_handle).
- setBoundingBox_(getBoxHandle_(element_handle), bounding_box); // insert
- // bounding_box
+ 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);
- setQuad_(element_handle, current_quad_handle); // set parent quad
- // (needed for removal
- // of element)
+ 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)
+ // 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) {
- setPrevElement_(element_handle, tail_element_handle);
- setNextElement_(tail_element_handle, element_handle);
+ set_prev_element_(element_handle, tail_element_handle);
+ set_next_element_(tail_element_handle, element_handle);
} else {
assert (head_element_handle == -1);
- setFirstElement_(current_quad_handle, element_handle);
+ set_first_element_(current_quad_handle, element_handle);
}
// assign the new tail
- setLastElement_(current_quad_handle, element_handle);
+ set_last_element_(current_quad_handle, element_handle);
- setLocalElementCount_(current_quad_handle,
- getLocalElementCount_(current_quad_handle) + 1);
+ set_local_element_count_(current_quad_handle, get_local_element_count_(current_quad_handle) + 1);
- if (canFlush_(current_quad_handle))
+ if (can_flush_(current_quad_handle))
flush_(current_height, current_extent, current_quad_handle);
return element_handle;
}
- private int disconnectElementHandle_(int 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 = getQuad_(element_handle);
- int head_element_handle = getFirstElement_(quad_handle);
- int tail_element_handle = getLastElement_(quad_handle);
- int prev_element_handle = getPrevElement_(element_handle);
- int next_element_handle = getNextElement_(element_handle);
+ 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)
- setPrevElement_(next_element_handle, -1);
+ set_prev_element_(next_element_handle, -1);
else {
assert (head_element_handle == tail_element_handle);
- assert (getLocalElementCount_(quad_handle) == 1);
- setLastElement_(quad_handle, -1);
+ assert (get_local_element_count_(quad_handle) == 1);
+ set_last_element_(quad_handle, -1);
}
- setFirstElement_(quad_handle, next_element_handle);
+ set_first_element_(quad_handle, next_element_handle);
} else if (tail_element_handle == element_handle) {
assert (prev_element_handle != -1);
- assert (getLocalElementCount_(quad_handle) >= 2);
- setNextElement_(prev_element_handle, -1);
- setLastElement_(quad_handle, prev_element_handle);
+ 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 (getLocalElementCount_(quad_handle) >= 3);
- setPrevElement_(next_element_handle, prev_element_handle);
- setNextElement_(prev_element_handle, next_element_handle);
+ 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);
}
- setPrevElement_(element_handle, -1);
- setNextElement_(element_handle, -1);
-
- setLocalElementCount_(quad_handle,
- getLocalElementCount_(quad_handle) - 1);
- assert (getLocalElementCount_(quad_handle) >= 0);
-
- return next_element_handle;
- }
-
- private static void setChildExtents_(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);
+ set_prev_element_(element_handle, -1);
+ set_next_element_(element_handle, -1);
- 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
+ set_local_element_count_(quad_handle, get_local_element_count_(quad_handle) - 1);
+ assert (get_local_element_count_(quad_handle) >= 0);
}
- private boolean canFlush_(int quad_handle) {
- return getLocalElementCount_(quad_handle) == 8
- && !hasChildren_(quad_handle);
+ 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;
+ Envelope2D bounding_box = new Envelope2D();
assert (quad_handle != -1);
- int element_handle = getFirstElement_(quad_handle), next_handle;
- int box_handle;
+ int element_handle = get_first_element_(quad_handle), next_handle = -1;
+ int data_handle = -1;
assert (element_handle != -1);
do {
- box_handle = getBoxHandle_(element_handle);
- element = m_element_nodes.getField(element_handle, 0);
- bounding_box = getBoundingBox_(box_handle);
- insert_(element, bounding_box, height, extent, quad_handle, true,
- element_handle);
+ 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);
- next_handle = getNextElement_(element_handle);
element_handle = next_handle;
} while (element_handle != -1);
}
- boolean canPushDown_(int quad_handle) {
- return getLocalElementCount_(quad_handle) >= 8
- || hasChildren_(quad_handle);
+ private boolean can_push_down_(int quad_handle) {
+ return get_local_element_count_(quad_handle) >= m_flushing_count || has_children_(quad_handle);
}
- boolean hasChildren_(int parent) {
- return getChild_(parent, 0) != -1 || getChild_(parent, 1) != -1
- || getChild_(parent, 2) != -1 || getChild_(parent, 3) != -1;
+ 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 createChild_(int parent, int quadrant) {
+ private int create_child_(int parent, int quadrant) {
int child = m_quad_tree_nodes.newElement();
- setChild_(parent, quadrant, child);
- setSubTreeElementCount_(child, 0);
- setLocalElementCount_(child, 0);
- setParent_(child, parent);
- setHeight_(child, getHeight_(parent) + 1);
- setMortenNumber_(child, (quadrant << (2 * getHeight_(parent)))
- | getMortenNumber_(parent));
+ 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 int createElementAndBoxNode_() {
+ 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 box_handle;
+ int data_handle;
- if (m_free_boxes.size() > 0) {
- box_handle = m_free_boxes.getLast();
- m_free_boxes.removeLast();
+ if (m_free_data.size() > 0) {
+ data_handle = m_free_data.get(m_free_data.size() - 1);
+ m_free_data.removeLast();
} else {
- box_handle = m_boxes.size();
- m_boxes.add(new Envelope2D());
+ data_handle = m_data.size();
+ m_data.add(null);
}
- setBoxHandle_(element_handle, box_handle);
+ 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 freeElementAndBoxNode_(int element_handle) {
- m_free_boxes.add(getBoxHandle_(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 getChild_(int quad_handle, int quadrant) {
+ private int get_child_(int quad_handle, int quadrant) {
return m_quad_tree_nodes.getField(quad_handle, quadrant);
}
- private void setChild_(int parent, int quadrant, int child) {
+ private void set_child_(int parent, int quadrant, int child) {
m_quad_tree_nodes.setField(parent, quadrant, child);
}
- private int getFirstElement_(int quad_handle) {
+ private int get_first_element_(int quad_handle) {
return m_quad_tree_nodes.getField(quad_handle, 4);
}
- private void setFirstElement_(int quad_handle, int head) {
+ private void set_first_element_(int quad_handle, int head) {
m_quad_tree_nodes.setField(quad_handle, 4, head);
}
- private int getLastElement_(int quad_handle) {
+ private int get_last_element_(int quad_handle) {
return m_quad_tree_nodes.getField(quad_handle, 5);
}
- private void setLastElement_(int quad_handle, int tail) {
+ private void set_last_element_(int quad_handle, int tail) {
m_quad_tree_nodes.setField(quad_handle, 5, tail);
}
- private int getMortenNumber_(int quad_handle) {
- return m_quad_tree_nodes.getField(quad_handle, 6);
+
+ 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 void setMortenNumber_(int quad_handle, int morten_number) {
- m_quad_tree_nodes.setField(quad_handle, 6, morten_number);
+ 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 int getLocalElementCount_(int quad_handle) {
- return m_quad_tree_nodes.getField(quad_handle, 7);
+ 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 getSubTreeElementCount_(int quad_handle) {
- return m_quad_tree_nodes.getField(quad_handle, 8);
+ private int get_local_element_count_(int quad_handle) {
+ return m_quad_tree_nodes.getField(quad_handle, 7);
}
- private void setLocalElementCount_(int quad_handle, int count) {
+ private void set_local_element_count_(int quad_handle, int count) {
m_quad_tree_nodes.setField(quad_handle, 7, count);
}
- private void setSubTreeElementCount_(int quad_handle, int 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 getParent_(int child) {
+ private int get_parent_(int child) {
return m_quad_tree_nodes.getField(child, 9);
}
- private void setParent_(int child, int parent) {
+ private void set_parent_(int child, int parent) {
m_quad_tree_nodes.setField(child, 9, parent);
}
- private int getHeight_(int quad_handle) {
- return (int) m_quad_tree_nodes.getField(quad_handle, 10);
+ private int get_contained_sub_tree_element_count_(int quad_handle) {
+ return m_quad_tree_nodes.getField(quad_handle, 10);
}
- private void setHeight_(int quad_handle, int height) {
- m_quad_tree_nodes.setField(quad_handle, 10, height);
+ private void set_contained_sub_tree_element_count_(int quad_handle, int count) {
+ m_quad_tree_nodes.setField(quad_handle, 10, count);
}
- private int getElement_(int element_handle) {
+ private int get_data_(int element_handle) {
return m_element_nodes.getField(element_handle, 0);
}
- private void setElement_(int element_handle, int element) {
- m_element_nodes.setField(element_handle, 0, element);
+ private void set_data_(int element_handle, int data_handle) {
+ m_element_nodes.setField(element_handle, 0, data_handle);
}
- private int getPrevElement_(int element_handle) {
+ private int get_prev_element_(int element_handle) {
return m_element_nodes.getField(element_handle, 1);
}
- private int getNextElement_(int element_handle) {
+ private int get_next_element_(int element_handle) {
return m_element_nodes.getField(element_handle, 2);
}
- private void setPrevElement_(int element_handle, int prev_handle) {
+ private void set_prev_element_(int element_handle, int prev_handle) {
m_element_nodes.setField(element_handle, 1, prev_handle);
}
- private void setNextElement_(int element_handle, int next_handle) {
+ private void set_next_element_(int element_handle, int next_handle) {
m_element_nodes.setField(element_handle, 2, next_handle);
}
- private int getQuad_(int element_handle) {
+ private int get_quad_(int element_handle) {
return m_element_nodes.getField(element_handle, 3);
}
- private void setQuad_(int element_handle, int parent) {
+ private void set_quad_(int element_handle, int parent) {
m_element_nodes.setField(element_handle, 3, parent);
}
- private int getBoxHandle_(int element_handle) {
- return m_element_nodes.getField(element_handle, 4);
+ private int get_element_value_(int data_handle) {
+ return m_data.get(data_handle).element;
}
- private void setBoxHandle_(int element_handle, int box_handle) {
- m_element_nodes.setField(element_handle, 4, box_handle);
+ private Envelope2D get_bounding_box_value_(int data_handle) {
+ return m_data.get(data_handle).box;
}
- private Envelope2D getBoundingBox_(int box_handle) {
- return m_boxes.get(box_handle);
+ private void set_data_values_(int data_handle, int element, Envelope2D bounding_box) {
+ m_data.set(data_handle, new Data(element, bounding_box));
}
- private void setBoundingBox_(int box_handle, Envelope2D bounding_box) {
- m_boxes.get(box_handle).setCoords(bounding_box);
- }
-
- private int m_root;
private Envelope2D m_extent;
- private int m_height;
+ private Envelope2D m_data_extent;
private StridedIndexTypeCollection m_quad_tree_nodes;
private StridedIndexTypeCollection m_element_nodes;
- private ArrayList m_boxes;
- private AttributeStreamOfInt32 m_free_boxes;
+ 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/main/java/com/esri/core/geometry/RasterizedGeometry2D.java b/src/main/java/com/esri/core/geometry/RasterizedGeometry2D.java
index 94f187d9..ff1b8257 100644
--- a/src/main/java/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.
@@ -136,4 +136,10 @@ static boolean canUseAccelerator(Geometry geom) {
*/
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
index 16e3dd1c..c7def2d4 100644
--- a/src/main/java/com/esri/core/geometry/RasterizedGeometry2DImpl.java
+++ b/src/main/java/com/esri/core/geometry/RasterizedGeometry2DImpl.java
@@ -24,18 +24,14 @@
package com.esri.core.geometry;
-import java.io.*;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import com.esri.core.geometry.Envelope2D;
-import com.esri.core.geometry.Geometry;
-import com.esri.core.geometry.GeometryException;
-import com.esri.core.geometry.NumberUtils;
-import com.esri.core.geometry.Point2D;
-import com.esri.core.geometry.Segment;
-import com.esri.core.geometry.SegmentIteratorImpl;
-import com.esri.core.geometry.SimpleRasterizer;
+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;
@@ -67,24 +63,39 @@ public ScanCallbackImpl(int[] bitmap, int scanlineWidth) {
}
public void setColor(SimpleRasterizer rasterizer, int color) {
+ if (m_color != color)
+ rasterizer.flush();
+
m_color = color;// set new color
}
@Override
- public void drawScan(int y, int x, int numPxls) {
- int x0 = x;
- int x1 = x + numPxls;
- if (x1 > m_width)
- x1 = m_width;
-
- 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
+ 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) {
@@ -122,33 +133,7 @@ void fillConvexPolygon(SimpleRasterizer rasterizer, Point2D[] fan, int len) {
}
void fillEnvelope(SimpleRasterizer rasterizer, Envelope2D envIn) {
- /*if (!m_identity) {
- Point2D fan[] = new Point2D[4];
- envIn.queryCorners(fan);
- fillConvexPolygon(rasterizer, fan, 4);
- return;
- }*/
-
- Envelope2D env = new Envelope2D(0, 0, m_width, m_width);
- if (!env.intersect(envIn))
- return;
-
- int x0 = (int) Math.round(env.xmin);
- int x = (int) Math.round(env.xmax);
-
- int xn = NumberUtils.snap(x0, 0, m_width);
- int xm = NumberUtils.snap(x, 0, m_width);
- if (x0 < m_width && xn < xm) {
- int y0 = (int) Math.round(env.ymin);
- int y1 = (int) Math.round(env.ymax);
- y0 = NumberUtils.snap(y0, 0, m_width);
- y1 = NumberUtils.snap(y1, 0, m_width);
- if (y0 < m_width) {
- for (int y = y0; y < y1; y++) {
- m_rasterizer.callback_.drawScan(y, xn, xm - xn);
- }
- }
- }
+ rasterizer.fillEnvelope(envIn);
}
void strokeDrawPolyPath(SimpleRasterizer rasterizer,
@@ -160,16 +145,15 @@ void strokeDrawPolyPath(SimpleRasterizer rasterizer,
SegmentIteratorImpl segIter = polyPath.querySegmentIterator();
double strokeHalfWidth = m_transform.transform(tol) + 1.5;
- double shortSegment = 0.5;
- Point2D vec = new Point2D();
- Point2D vecA = new Point2D();
- Point2D vecB = new Point2D();
- // TODO check this Java workaroung
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;
@@ -177,18 +161,23 @@ void strokeDrawPolyPath(SimpleRasterizer rasterizer,
while (segIter.hasNextSegment()) {
Segment seg = segIter.nextSegment();
ptStart.x = seg.getStartX();
- ptStart.y = seg.getStartY();// Point2D ptStart =
- // seg.getStartXY();
+ ptStart.y = seg.getStartY();
ptEnd.x = seg.getEndX();
- ptEnd.y = seg.getEndY();// Point2D ptEnd = seg.getEndXY();
+ 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) {
- fillConvexPolygon(rasterizer, fan, 4);
+ 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;
}
@@ -203,43 +192,41 @@ void strokeDrawPolyPath(SimpleRasterizer rasterizer,
ptStart.setCoords(ptOld);
}
- vec.sub(ptEnd, ptStart);
- double len = vec.length();
- boolean bShort = len < shortSegment;
- if (len == 0) {
- vec.setCoords(1.0, 0);
- len = 1.0;
- continue;
+ 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 (!bShort)
- ptOld.setCoords(ptEnd);
-
- vec.scale(strokeHalfWidth / len);
- vecA.setCoords(-vec.y, vec.x);
- vecB.setCoords(vec.y, -vec.x);
- ptStart.sub(vec);
- ptEnd.add(vec);
- fan[0].add(ptStart, vecA);
- fan[1].add(ptStart, vecB);
- fan[2].add(ptEnd, vecB);
- fan[3].add(ptEnd, vecA);
- if (!bShort)
- fillConvexPolygon(rasterizer, fan, 4);
- else
- hasFan = true;
+ 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;
}
- if (hasFan)
- fillConvexPolygon(rasterizer, fan, 4);
}
}
int worldToPixX(double x) {
- return (int) Math.round(x * m_dx + m_x0);
+ return (int) (x * m_dx + m_x0);
}
int worldToPixY(double y) {
- return (int) Math.round(y * m_dy + m_y0);
+ return (int) (y * m_dy + m_y0);
}
RasterizedGeometry2DImpl(Geometry geom, double toleranceXY,
@@ -253,8 +240,7 @@ static RasterizedGeometry2DImpl createImpl(Geometry geom,
double toleranceXY, int rasterSizeBytes) {
RasterizedGeometry2DImpl rgImpl = new RasterizedGeometry2DImpl(geom,
toleranceXY, rasterSizeBytes);
- rgImpl.init((MultiVertexGeometryImpl) geom._getImpl(), toleranceXY,
- rasterSizeBytes);
+
return rgImpl;
}
@@ -267,7 +253,6 @@ static RasterizedGeometry2DImpl createImpl(MultiVertexGeometryImpl geom,
double toleranceXY, int rasterSizeBytes) {
RasterizedGeometry2DImpl rgImpl = new RasterizedGeometry2DImpl(geom,
toleranceXY, rasterSizeBytes);
- rgImpl.init(geom, toleranceXY, rasterSizeBytes);
return rgImpl;
}
@@ -332,12 +317,10 @@ void init(MultiVertexGeometryImpl geom, double toleranceXY,
m_transform = new Transformation2D();
m_transform.initializeFromRect(worldEnv, pixEnv);// geom to pixels
- Transformation2D identityTransform = new Transformation2D();
-
switch (geom.getType().value()) {
case Geometry.GeometryType.MultiPoint:
callback.setColor(m_rasterizer, 2);
- fillPoints(m_rasterizer, (MultiPointImpl) geom, m_stroke_half_width);
+ fillPoints(m_rasterizer, (MultiPointImpl) geom, m_stroke_half_width);
break;
case Geometry.GeometryType.Polyline:
callback.setColor(m_rasterizer, 2);
@@ -360,6 +343,7 @@ void init(MultiVertexGeometryImpl geom, double toleranceXY,
m_x0 = m_transform.xd;
m_y0 = m_transform.yd;
buildLevels();
+ //dbgSaveToBitmap("c:/temp/_dbg.bmp");
}
boolean tryRenderAsSmallEnvelope_(Envelope2D env) {
@@ -389,6 +373,7 @@ boolean tryRenderAsSmallEnvelope_(Envelope2D env) {
}
void buildLevels() {
+ m_rasterizer.flush();
int iStart = 0;
int iStartNext = m_width * m_scanLineSize;
int width = m_width;
@@ -427,6 +412,9 @@ void buildLevels() {
@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)
@@ -445,7 +433,8 @@ else if (res == 1)
@Override
public HitType queryEnvelopeInGeometry(Envelope2D env) {
if (!env.intersect(m_geomEnv))
- return com.esri.core.geometry.RasterizedGeometry2D.HitType.Outside;
+ return HitType.Outside;
+
int ixmin = worldToPixX(env.xmin);
int ixmax = worldToPixX(env.xmax);
int iymin = worldToPixY(env.ymin);
@@ -563,7 +552,6 @@ public boolean dbgSaveToBitmap(String fileName) {
// int32_t* rgb4 = (int32_t*)malloc(biSizeImage);
for (int y = 0; y < height; y++) {
int scanlineIn = y * ((width * 2 + 31) / 32);
- int scanlineOut = offset + width * y;
for (int x = 0; x < width; x++) {
int res = (m_bitmap[scanlineIn + (x >> 4)] >> ((x & 15) * 2)) & 3;
@@ -580,4 +568,14 @@ public boolean dbgSaveToBitmap(String fileName) {
}
}
+
+ @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/main/java/com/esri/core/geometry/RelationalOperations.java b/src/main/java/com/esri/core/geometry/RelationalOperations.java
index 08d60ca3..abf03372 100644
--- a/src/main/java/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.
@@ -1139,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.
@@ -1179,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.
@@ -1234,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.
@@ -1540,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);
}
@@ -1716,14 +1787,16 @@ private static boolean polylineTouchesMultiPoint_(Polyline polyline_a,
envInter.setCoords(env_a);
envInter.intersect(env_b);
- QuadTreeImpl qtA;
- QuadTreeImpl quadTreeA;
+ 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);
@@ -1737,6 +1810,10 @@ private static boolean polylineTouchesMultiPoint_(Polyline polyline_a,
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;
@@ -1755,6 +1832,14 @@ private static boolean polylineTouchesMultiPoint_(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)
+ continue;
+ }
+
qtIterA.resetIterator(env_b, tolerance);
for (int elementHandleA = qtIterA.next(); elementHandleA != -1; elementHandleA = qtIterA
@@ -1818,14 +1903,16 @@ private static boolean polylineCrossesMultiPoint_(Polyline polyline_a,
envInter.setCoords(env_a);
envInter.intersect(env_b);
- QuadTreeImpl qtA;
- QuadTreeImpl quadTreeA;
+ 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);
@@ -1839,7 +1926,11 @@ private static boolean polylineCrossesMultiPoint_(Polyline polyline_a,
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;
@@ -1859,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;
@@ -3071,71 +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, 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();
-
- boolean b_simple_a = multi_path_impl_a.getIsSimple(0.0) >= 1;
- boolean b_simple_b = multi_path_impl_b.getIsSimple(0.0) >= 1;
- Envelope2DIntersectorImpl intersector = InternalUtils
- .getEnvelope2DIntersectorForParts(multi_path_impl_a,
- multi_path_impl_b, tolerance, b_simple_a, b_simple_b);
-
- if (intersector != null) {
- if (!intersector.next()) {
- return true; // no rings intersect
- }
- } else {
- return true; // no rings intersect
- }
-
- boolean b_intersects = linearPathIntersectsLinearPath_(polygon_a,
- multipath_b, tolerance);
-
- if (b_intersects) {
- return false;
- }
-
- do {
- int index_a = intersector.getHandleA();
- int index_b = intersector.getHandleB();
- int path_a = intersector.getRedElement(index_a);
- int path_b = intersector.getBlueElement(index_b);
-
- pt_b = multipath_b.getXY(multipath_b.getPathStart(path_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() == Geometry.Type.Polygon) {
- pt_a = polygon_a.getXY(polygon_a.getPathStart(path_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;
- }
- }
- }
- } while (intersector.next());
-
- 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.
@@ -3448,14 +3577,16 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
SegmentIteratorImpl segIterB = ((MultiPathImpl) multipathB._getImpl())
.querySegmentIterator();
- QuadTreeImpl qtB;
- QuadTreeImpl quadTreeB;
+ 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);
@@ -3469,6 +3600,10 @@ private static boolean linearPathWithinLinearPath_(MultiPath multipathA,
QuadTreeImpl.QuadTreeIteratorImpl qtIterB = quadTreeB.getIterator();
+ QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsB = null;
+ if (quadTreePathsB != null)
+ qtIterPathsB = quadTreePathsB.getIterator();
+
while (segIterA.nextPath()) {
while (segIterA.hasNextSegment()) {
boolean bStringOfSegmentAsCovered = false;
@@ -3480,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);
@@ -3709,14 +3853,16 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
int_point = new Point2D();
}
- QuadTreeImpl qtB;
- QuadTreeImpl quadTreeB;
+ 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);
@@ -3730,6 +3876,10 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
QuadTreeImpl.QuadTreeIteratorImpl qtIterB = quadTreeB.getIterator();
+ QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsB = null;
+ if (quadTreePathsB != null)
+ qtIterPathsB = quadTreePathsB.getIterator();
+
while (segIterA.nextPath()) {
overlapLength = 0.0;
@@ -3741,6 +3891,13 @@ static int linearPathIntersectsLinearPathMaxDim_(MultiPath _multipathA,
continue;
}
+ if (qtIterPathsB != null) {
+ qtIterPathsB.resetIterator(env_a, tolerance);
+
+ if (qtIterPathsB.next() == -1)
+ continue;
+ }
+
double lengthA = segmentA.calculateLength2D();
qtIterB.resetIterator(segmentA, tolerance);
@@ -3954,12 +4111,11 @@ private static boolean linearPathIntersectsLinearPath_(
SegmentIteratorImpl segIterA = multi_path_impl_a.querySegmentIterator();
SegmentIteratorImpl segIterB = multi_path_impl_b.querySegmentIterator();
- Pair_wise_intersector intersector = new Pair_wise_intersector(
- multi_path_impl_a, multi_path_impl_b, tolerance);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(multi_path_impl_a, multi_path_impl_b, tolerance, false);
while (intersector.next()) {
- int vertex_a = intersector.get_red_element();
- int vertex_b = intersector.get_blue_element();
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
segIterA.resetToVertex(vertex_a);
segIterB.resetToVertex(vertex_b);
@@ -3986,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();
@@ -3996,22 +4149,20 @@ 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 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);
@@ -4024,8 +4175,12 @@ private static boolean linearPathIntersectsMultiPoint_(
}
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++) {
@@ -4035,8 +4190,15 @@ private static boolean linearPathIntersectsMultiPoint_(
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;
@@ -4341,14 +4503,14 @@ private static boolean polygonTouchesPolygonImpl_(Polygon polygon_a,
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Pair_wise_intersector intersector = new Pair_wise_intersector(
- polygon_impl_a, polygon_impl_b, tolerance);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polygon_impl_b, tolerance, false);
boolean b_boundaries_intersect = false;
while (intersector.next()) {
- int vertex_a = intersector.get_red_element();
- int vertex_b = intersector.get_blue_element();
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
segIterA.resetToVertex(vertex_a);
segIterB.resetToVertex(vertex_b);
@@ -4450,12 +4612,12 @@ private static boolean polygonOverlapsPolygonImpl_(Polygon polygon_a,
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Pair_wise_intersector intersector = new Pair_wise_intersector(
- polygon_impl_a, polygon_impl_b, tolerance);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polygon_impl_b, tolerance, false);
while (intersector.next()) {
- int vertex_a = intersector.get_red_element();
- int vertex_b = intersector.get_blue_element();
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
segIterA.resetToVertex(vertex_a);
segIterB.resetToVertex(vertex_b);
@@ -4552,65 +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();
- double[] scalarsA = new double[2];
- double[] scalarsB = new double[2];
-
- Pair_wise_intersector intersector = new Pair_wise_intersector(
- polygon_impl_a, polygon_impl_b, tolerance);
-
- while (intersector.next()) {
- int vertex_a = intersector.get_red_element();
- int vertex_b = intersector.get_blue_element();
-
- 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) {
@@ -4622,14 +4899,14 @@ private static boolean polygonTouchesPolylineImpl_(Polygon polygon_a,
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Pair_wise_intersector intersector = new Pair_wise_intersector(
- polygon_impl_a, polyline_impl_b, tolerance);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polyline_impl_b, tolerance, false);
boolean b_boundaries_intersect = false;
while (intersector.next()) {
- int vertex_a = intersector.get_red_element();
- int vertex_b = intersector.get_blue_element();
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
segIterA.resetToVertex(vertex_a);
segIterB.resetToVertex(vertex_b);
@@ -4708,14 +4985,14 @@ private static boolean polygonCrossesPolylineImpl_(Polygon polygon_a,
double[] scalarsA = new double[2];
double[] scalarsB = new double[2];
- Pair_wise_intersector intersector = new Pair_wise_intersector(
- polygon_impl_a, polyline_impl_b, tolerance);
+ PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(
+ polygon_impl_a, polyline_impl_b, tolerance, false);
boolean b_boundaries_intersect = false;
while (intersector.next()) {
- int vertex_a = intersector.get_red_element();
- int vertex_b = intersector.get_blue_element();
+ int vertex_a = intersector.getRedElement();
+ int vertex_b = intersector.getBlueElement();
segIterA.resetToVertex(vertex_a);
segIterB.resetToVertex(vertex_b);
@@ -4796,82 +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();
- double[] scalarsA = new double[2];
- double[] scalarsB = new double[2];
-
- Pair_wise_intersector intersector = new Pair_wise_intersector(
- polygon_impl_a, polyline_impl_b, tolerance);
-
- boolean b_boundaries_intersect = false;
-
- while (intersector.next()) {
- int vertex_a = intersector.get_red_element();
- int vertex_b = intersector.get_blue_element();
-
- 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,
@@ -4917,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,
@@ -4930,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;
}
}
@@ -4987,171 +5216,6 @@ int compareOverlapEvents_(int o_1, int o_2) {
return 1;
}
- static final class Pair_wise_intersector {
-
- Pair_wise_intersector(MultiPathImpl multi_path_impl_a,
- MultiPathImpl multi_path_impl_b, double tolerance) {
- m_b_quad_tree = false;
-
- GeometryAccelerators geometry_accelerators_a = multi_path_impl_a
- ._getAccelerators();
-
- if (geometry_accelerators_a != null) {
- QuadTreeImpl qtree_a = geometry_accelerators_a.getQuadTree();
-
- 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_seg_iter = multi_path_impl_b.querySegmentIterator();
- m_function = State.next_path;
- }
- }
-
- if (!m_b_quad_tree) {
- GeometryAccelerators geometry_accelerators_b = multi_path_impl_b
- ._getAccelerators();
-
- if (geometry_accelerators_b != null) {
- QuadTreeImpl qtree_b = geometry_accelerators_b
- .getQuadTree();
-
- 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_seg_iter = multi_path_impl_a.querySegmentIterator();
- m_function = State.next_path;
- }
- }
- }
-
- if (!m_b_quad_tree) {
- m_intersector = InternalUtils.getEnvelope2DIntersector(
- multi_path_impl_a, multi_path_impl_b, tolerance);
- }
- }
-
- 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.next_path:
- b_searching = next_path_();
- break;
- case State.next_segment:
- b_searching = next_segment_();
- break;
- case State.iterate:
- b_searching = iterate_();
- break;
- }
-
- }
-
- if (m_b_done) {
- return false;
- }
-
- return true;
- }
-
- if (m_intersector == null) {
- return false;
- }
-
- return m_intersector.next();
- }
-
- int get_red_element() {
- if (m_b_quad_tree) {
- if (!m_b_swap_elements) {
- return m_seg_iter.getStartPointIndex();
- }
-
- return m_quad_tree.getElement(m_element_handle);
- }
-
- return m_intersector.getRedElement(m_intersector.getHandleA());
- }
-
- int get_blue_element() {
- if (m_b_quad_tree) {
- if (m_b_swap_elements) {
- return m_seg_iter.getStartPointIndex();
- }
-
- return m_quad_tree.getElement(m_element_handle);
- }
-
- return m_intersector.getBlueElement(m_intersector.getHandleB());
- }
-
- private boolean next_path_() {
- if (!m_seg_iter.nextPath()) {
- m_b_done = true;
- return false;
- }
-
- m_function = State.next_segment;
- return true;
- }
-
- private boolean next_segment_() {
- if (!m_seg_iter.hasNextSegment()) {
- m_function = State.next_path;
- 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 = State.next_segment;
- return true;
- }
-
- return false;
- }
-
- private interface State {
-
- static final int next_path = 0;
- static final int next_segment = 1;
- static final int iterate = 2;
- }
-
- // Quad_tree
- private boolean m_b_quad_tree;
- private boolean m_b_done;
- private boolean m_b_swap_elements;
- private double m_tolerance;
- private int m_element_handle;
- private QuadTreeImpl m_quad_tree;
- private QuadTreeImpl.QuadTreeIteratorImpl m_qt_iter;
- private SegmentIteratorImpl m_seg_iter;
- private int m_function;
-
- // Envelope_2D_intersector
- private Envelope2DIntersectorImpl m_intersector;
- }
-
static final class Accelerate_helper {
static boolean accelerate_geometry(Geometry geometry,
SpatialReference sr,
@@ -5173,18 +5237,18 @@ static boolean accelerate_geometry(Geometry geometry,
bAccelerated |= ((MultiVertexGeometryImpl) geometry._getImpl())
._buildQuadTreeAccelerator(accel_degree);
- if (type == Geometry.Type.Polygon
- && GeometryAccelerators.canUsePathEnvelopes(geometry)
+ if ((type == Geometry.Type.Polygon || type == Geometry.Type.Polyline)
+ && GeometryAccelerators.canUseQuadTreeForPaths(geometry)
&& accel_degree != Geometry.GeometryAccelerationDegree.enumMild)
bAccelerated |= ((MultiPathImpl) geometry._getImpl())
- ._buildPathEnvelopesAccelerator(accel_degree);
+ ._buildQuadTreeForPathsAccelerator(accel_degree);
return bAccelerated;
}
- static boolean can_accelerate_geometry(Geometry geometry) {
- return GeometryAccelerators.canUseRasterizedGeometry(geometry)
- || GeometryAccelerators.canUseQuadTree(geometry);
- }
- }
+ 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
index a3b3f02d..1d93f5c8 100644
--- a/src/main/java/com/esri/core/geometry/RelationalOperationsMatrix.java
+++ b/src/main/java/com/esri/core/geometry/RelationalOperationsMatrix.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,9 +26,11 @@
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;
+ 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;
@@ -60,7 +62,19 @@ private interface Predicates {
// string.
static boolean relate(Geometry geometry_a, Geometry geometry_b,
SpatialReference sr, String scl, ProgressTracker progress_tracker) {
- int relation = getPredefinedRelation_(scl, geometry_a.getDimension(),
+
+ 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)
@@ -81,6 +95,9 @@ static boolean relate(Geometry geometry_a, Geometry geometry_b,
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();
@@ -218,7 +235,10 @@ 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.
@@ -238,7 +258,7 @@ static boolean polygonRelatePolygon_(Polygon polygon_a, Polygon polygon_b,
env_a, env_b, tolerance, progress_tracker);
if (b_disjoint) {
- relOps.areaAreaDisjointPredicates_();
+ relOps.areaAreaDisjointPredicates_(polygon_a, polygon_b);
bRelationKnown = true;
}
@@ -250,13 +270,13 @@ static boolean polygonRelatePolygon_(Polygon polygon_a, Polygon polygon_b,
tolerance, false);
if (relation == RelationalOperations.Relation.disjoint) {
- relOps.areaAreaDisjointPredicates_();
+ relOps.areaAreaDisjointPredicates_(polygon_a, polygon_b);
bRelationKnown = true;
} else if (relation == RelationalOperations.Relation.contains) {
- relOps.areaAreaContainsPredicates_();
+ relOps.areaAreaContainsPredicates_(polygon_b);
bRelationKnown = true;
} else if (relation == RelationalOperations.Relation.within) {
- relOps.areaAreaWithinPredicates_();
+ relOps.areaAreaWithinPredicates_(polygon_a);
bRelationKnown = true;
}
}
@@ -275,6 +295,108 @@ static boolean polygonRelatePolygon_(Polygon polygon_a, Polygon polygon_b,
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,
@@ -293,7 +415,7 @@ static boolean polygonRelatePolyline_(Polygon polygon_a,
env_a, env_b, tolerance, progress_tracker);
if (b_disjoint) {
- relOps.areaLineDisjointPredicates_(polyline_b); // passing polyline
+ relOps.areaLineDisjointPredicates_(polygon_a, polyline_b); // passing polyline
// to get boundary
// information
bRelationKnown = true;
@@ -307,13 +429,13 @@ static boolean polygonRelatePolyline_(Polygon polygon_a,
tolerance, false);
if (relation == RelationalOperations.Relation.disjoint) {
- relOps.areaLineDisjointPredicates_(polyline_b); // passing
+ relOps.areaLineDisjointPredicates_(polygon_a, polyline_b); // passing
// polyline to
// get boundary
// information
bRelationKnown = true;
} else if (relation == RelationalOperations.Relation.contains) {
- relOps.areaLineContainsPredicates_(polyline_b); // passing
+ relOps.areaLineContainsPredicates_(polygon_a, polyline_b); // passing
// polyline to
// get boundary
// information
@@ -341,6 +463,66 @@ static boolean polygonRelatePolyline_(Polygon polygon_a,
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,
@@ -359,7 +541,7 @@ static boolean polygonRelateMultiPoint_(Polygon polygon_a,
env_a, env_b, tolerance, progress_tracker);
if (b_disjoint) {
- relOps.areaPointDisjointPredicates_();
+ relOps.areaPointDisjointPredicates_(polygon_a);
bRelationKnown = true;
}
@@ -371,10 +553,10 @@ static boolean polygonRelateMultiPoint_(Polygon polygon_a,
tolerance, false);
if (relation == RelationalOperations.Relation.disjoint) {
- relOps.areaPointDisjointPredicates_();
+ relOps.areaPointDisjointPredicates_(polygon_a);
bRelationKnown = true;
} else if (relation == RelationalOperations.Relation.contains) {
- relOps.areaPointContainsPredicates_();
+ relOps.areaPointContainsPredicates_(polygon_a);
bRelationKnown = true;
}
}
@@ -548,144 +730,189 @@ static boolean multiPointRelateMultiPoint_(MultiPoint multipoint_a,
// 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_();
- bRelationKnown = true;
- }
-
- if (!bRelationKnown) {
- PolygonUtils.PiPResult res = PolygonUtils.isPointInPolygon2D(
- polygon_a, pt_b, tolerance); // uses accelerator
-
- if (res == PolygonUtils.PiPResult.PiPInside) {
- relOps.m_matrix[MatrixPredicate.InteriorInterior] = 0;
- relOps.m_matrix[MatrixPredicate.BoundaryInterior] = -1;
- relOps.m_matrix[MatrixPredicate.ExteriorInterior] = -1;
- } else if (res == PolygonUtils.PiPResult.PiPBoundary) {
- relOps.m_matrix[MatrixPredicate.InteriorInterior] = -1;
- relOps.m_matrix[MatrixPredicate.BoundaryInterior] = 0;
- relOps.m_matrix[MatrixPredicate.ExteriorInterior] = -1;
- } else {
- relOps.m_matrix[MatrixPredicate.InteriorInterior] = -1;
- relOps.m_matrix[MatrixPredicate.ExteriorInterior] = 0;
- relOps.m_matrix[MatrixPredicate.ExteriorInterior] = -1;
- }
- }
-
- boolean bRelation = relationCompare_(relOps.m_matrix, scl);
- return bRelation;
+ 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);
- }
- }
- }
- }
-
- boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
- return bRelation;
+ 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.
@@ -812,6 +1039,85 @@ private static boolean relationCompare_(int[] matrix, String scl) {
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))
@@ -971,36 +1277,41 @@ private static boolean overlaps_(String scl, int dim_a, int dim_b) {
// the geometry and/or a boundary index of the geometry.
private static void markClusterEndPoints_(int geometry,
TopoGraph topoGraph, int clusterIndex) {
- EditShape edit_shape = topoGraph.getShape();
+ int id = topoGraph.getGeometryID(geometry);
- for (int path = edit_shape.getFirstPath(geometry); path != -1; path = edit_shape
- .getNextPath(path)) {
- int vertexFirst = edit_shape.getFirstVertex(path);
- int vertexLast = edit_shape.getLastVertex(path);
- boolean b_closed = (vertexFirst == vertexLast);
+ for (int cluster = topoGraph.getFirstCluster(); cluster != -1; cluster = topoGraph.getNextCluster(cluster))
+ {
+ int cluster_parentage = topoGraph.getClusterParentage(cluster);
- int vertex = vertexFirst;
+ if ((cluster_parentage & id) == 0)
+ continue;
- do {
- int cluster = topoGraph.getClusterFromVertex(vertex);
- int index = topoGraph
- .getClusterUserIndex(cluster, clusterIndex);
-
- if (!b_closed
- && (vertex == vertexFirst || vertex == vertexLast)) {
- if (index == -1)
- topoGraph.setClusterUserIndex(cluster, clusterIndex, 1);
- else
- topoGraph.setClusterUserIndex(cluster, clusterIndex,
- index + 1);
- } else {
- if (index == -1)
- topoGraph.setClusterUserIndex(cluster, clusterIndex, 0);
- }
+ int first_half_edge = topoGraph.getClusterHalfEdge(cluster);
+ if (first_half_edge == -1)
+ {
+ topoGraph.setClusterUserIndex(cluster, clusterIndex, 0);
+ continue;
+ }
- vertex = edit_shape.getNextVertex(vertex);
- } while (vertex != vertexFirst && vertex != -1);
- }
+ 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) {
@@ -1025,21 +1336,24 @@ private static String getTransposeMatrix_(String scl) {
// 2: 2-dimension intersection
private void resetMatrix_() {
for (int i = 0; i < 9; i++)
- m_matrix[i] = -2;
+ {
+ m_matrix[i] = -2;
+ m_max_dim[i] = -2;
+ }
}
- private void transposeMatrix_() {
- int temp1 = m_matrix[1];
- int temp2 = m_matrix[2];
- int temp5 = m_matrix[5];
+ private static void transposeMatrix_(int[] matrix) {
+ int temp1 = matrix[1];
+ int temp2 = matrix[2];
+ int temp5 = matrix[5];
- m_matrix[1] = m_matrix[3];
- m_matrix[2] = m_matrix[6];
- m_matrix[5] = m_matrix[7];
+ matrix[1] = matrix[3];
+ matrix[2] = matrix[6];
+ matrix[5] = matrix[7];
- m_matrix[3] = temp1;
- m_matrix[6] = temp2;
- m_matrix[7] = temp5;
+ matrix[3] = temp1;
+ matrix[6] = temp2;
+ matrix[7] = temp5;
}
// Sets the relation predicates from the scl string.
@@ -1066,193 +1380,254 @@ private void setRemainingPredicatesToFalse_() {
}
// Checks whether the predicate is known.
- private boolean isPredicateKnown_(int predicate, int dim) {
- 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] < dim) {
- return false;
- } else {
- m_perform_predicates[predicate] = false;
- m_predicate_count--;
- return true;
- }
- } else {
- m_perform_predicates[predicate] = false;
- m_predicate_count--;
- return true;
- }
+ 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 = Predicates.AreaAreaPredicates;
-
- // 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--;
- }
+ 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 = Predicates.AreaLinePredicates;
-
- // set predicates that are always true/false
- if (m_perform_predicates[MatrixPredicate.InteriorExterior]) {
- m_matrix[MatrixPredicate.InteriorExterior] = 2; // Always true
- m_perform_predicates[MatrixPredicate.InteriorExterior] = 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--;
- }
+ 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 = Predicates.LineLinePredicates;
-
- // 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--;
- }
+ 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 = Predicates.AreaPointPredicates;
-
- // 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.InteriorExterior]) {
- m_matrix[MatrixPredicate.InteriorExterior] = 2; // Always true
- m_perform_predicates[MatrixPredicate.InteriorExterior] = 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 true
- 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--;
- }
+ 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 = Predicates.LinePointPredicates;
-
- // 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.InteriorExterior]) {
- m_matrix[MatrixPredicate.InteriorExterior] = 1; // Always true
- m_perform_predicates[MatrixPredicate.InteriorExterior] = 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--;
- }
+ 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 = Predicates.PointPointPredicates;
-
- // 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--;
- }
+ 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.
@@ -1262,175 +1637,228 @@ private boolean areaAreaPredicates_(int half_edge, int id_a, int id_b) {
if (m_perform_predicates[MatrixPredicate.InteriorInterior]) {
interiorAreaInteriorArea_(half_edge, id_a, id_b);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorInterior, 2);
+ MatrixPredicate.InteriorInterior);
}
if (m_perform_predicates[MatrixPredicate.InteriorBoundary]) {
interiorAreaBoundaryArea_(half_edge, id_a,
MatrixPredicate.InteriorBoundary);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorBoundary, 1);
+ MatrixPredicate.InteriorBoundary);
}
if (m_perform_predicates[MatrixPredicate.InteriorExterior]) {
interiorAreaExteriorArea_(half_edge, id_a, id_b,
MatrixPredicate.InteriorExterior);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorExterior, 2);
+ MatrixPredicate.InteriorExterior);
}
if (m_perform_predicates[MatrixPredicate.BoundaryInterior]) {
interiorAreaBoundaryArea_(half_edge, id_b,
MatrixPredicate.BoundaryInterior);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryInterior, 1);
+ MatrixPredicate.BoundaryInterior);
}
if (m_perform_predicates[MatrixPredicate.BoundaryBoundary]) {
boundaryAreaBoundaryArea_(half_edge, id_a, id_b);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryBoundary, 1);
+ MatrixPredicate.BoundaryBoundary);
}
if (m_perform_predicates[MatrixPredicate.BoundaryExterior]) {
boundaryAreaExteriorArea_(half_edge, id_a, id_b,
MatrixPredicate.BoundaryExterior);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryExterior, 1);
+ MatrixPredicate.BoundaryExterior);
}
if (m_perform_predicates[MatrixPredicate.ExteriorInterior]) {
interiorAreaExteriorArea_(half_edge, id_b, id_a,
MatrixPredicate.ExteriorInterior);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorInterior, 2);
+ MatrixPredicate.ExteriorInterior);
}
if (m_perform_predicates[MatrixPredicate.ExteriorBoundary]) {
boundaryAreaExteriorArea_(half_edge, id_b, id_a,
MatrixPredicate.ExteriorBoundary);
bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorBoundary, 1);
+ MatrixPredicate.ExteriorBoundary);
}
return bRelationKnown;
}
- private void areaAreaDisjointPredicates_() {
- m_matrix[MatrixPredicate.InteriorInterior] = -1;
- m_matrix[MatrixPredicate.InteriorBoundary] = -1;
- m_matrix[MatrixPredicate.InteriorExterior] = 2;
- m_matrix[MatrixPredicate.BoundaryInterior] = -1;
- m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
- m_matrix[MatrixPredicate.BoundaryExterior] = 1;
- m_matrix[MatrixPredicate.ExteriorInterior] = 2;
- m_matrix[MatrixPredicate.ExteriorBoundary] = 1;
-
- // all other predicates should already be set by
- // set_area_area_predicates
- }
-
- private void areaAreaContainsPredicates_() {
- m_matrix[MatrixPredicate.InteriorInterior] = 2;
- m_matrix[MatrixPredicate.InteriorBoundary] = 1;
- m_matrix[MatrixPredicate.InteriorExterior] = 2;
- 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;
-
- // all other predicates should already be set by
- // set_area_area_predicates
- }
-
- private void areaAreaWithinPredicates_() {
- areaAreaContainsPredicates_();
- transposeMatrix_();
- }
-
- private void areaLineDisjointPredicates_(Polyline polyline) {
- m_matrix[MatrixPredicate.InteriorInterior] = -1;
- m_matrix[MatrixPredicate.InteriorBoundary] = -1;
- m_matrix[MatrixPredicate.BoundaryInterior] = -1;
- m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
- m_matrix[MatrixPredicate.BoundaryExterior] = 1;
- m_matrix[MatrixPredicate.ExteriorInterior] = 1;
-
- 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);
- }
- }
-
- private void areaLineContainsPredicates_(Polyline polyline) {
- m_matrix[MatrixPredicate.InteriorInterior] = 1;
-
- 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.BoundaryInterior] = -1;
- m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
- m_matrix[MatrixPredicate.BoundaryExterior] = 1;
- m_matrix[MatrixPredicate.ExteriorInterior] = -1;
- m_matrix[MatrixPredicate.ExteriorBoundary] = -1;
- }
-
- private void areaPointDisjointPredicates_() {
- m_matrix[MatrixPredicate.InteriorInterior] = -1;
- m_matrix[MatrixPredicate.BoundaryInterior] = -1;
- m_matrix[MatrixPredicate.ExteriorInterior] = 0;
- }
-
- private void areaPointContainsPredicates_() {
- m_matrix[MatrixPredicate.InteriorInterior] = 0;
- m_matrix[MatrixPredicate.BoundaryInterior] = -1;
- m_matrix[MatrixPredicate.ExteriorInterior] = -1;
- }
+ 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.InteriorExterior] = 1;
- m_matrix[MatrixPredicate.BoundaryInterior] = -1;
- m_matrix[MatrixPredicate.BoundaryBoundary] = -1;
-
- 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);
- }
-
- m_matrix[MatrixPredicate.ExteriorInterior] = 1;
-
- 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);
- }
+ 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;
+ m_matrix[MatrixPredicate.InteriorInterior] = -1;
+ m_matrix[MatrixPredicate.BoundaryInterior] = -1;
- 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);
- }
+ 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);
+ }
- m_matrix[MatrixPredicate.ExteriorInterior] = 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_() {
@@ -1441,197 +1869,211 @@ private void pointPointDisjointPredicates_() {
// 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, 1);
- }
-
- if (m_perform_predicates[MatrixPredicate.InteriorBoundary]) {
- interiorAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorBoundary, 0);
- }
-
- if (m_perform_predicates[MatrixPredicate.BoundaryInterior]) {
- boundaryAreaInteriorLine_(half_edge, id_a, id_b, m_cluster_index_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryInterior, 1);
- }
-
- if (m_perform_predicates[MatrixPredicate.BoundaryBoundary]) {
- boundaryAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryBoundary, 0);
- }
-
- if (m_perform_predicates[MatrixPredicate.BoundaryExterior]) {
- boundaryAreaExteriorLine_(half_edge, id_a, id_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryExterior, 1);
- }
-
- if (m_perform_predicates[MatrixPredicate.ExteriorInterior]) {
- exteriorAreaInteriorLine_(half_edge, id_a);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorInterior, 1);
- }
-
- if (m_perform_predicates[MatrixPredicate.ExteriorBoundary]) {
- exteriorAreaBoundaryLine_(half_edge, id_a, id_b, m_cluster_index_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorBoundary, 0);
- }
-
- return bRelationKnown;
+ 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, 1);
- }
-
- 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, 0);
- }
-
- if (m_perform_predicates[MatrixPredicate.InteriorExterior]) {
- interiorLineExteriorLine_(half_edge, id_a, id_b,
- MatrixPredicate.InteriorExterior);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorExterior, 1);
- }
-
- 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, 0);
- }
-
- 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, 0);
- }
-
- if (m_perform_predicates[MatrixPredicate.BoundaryExterior]) {
- boundaryLineExteriorLine_(half_edge, id_a, id_b, m_cluster_index_a,
- MatrixPredicate.BoundaryExterior);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryExterior, 0);
- }
-
- if (m_perform_predicates[MatrixPredicate.ExteriorInterior]) {
- interiorLineExteriorLine_(half_edge, id_b, id_a,
- MatrixPredicate.ExteriorInterior);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorInterior, 1);
- }
-
- if (m_perform_predicates[MatrixPredicate.ExteriorBoundary]) {
- boundaryLineExteriorLine_(half_edge, id_b, id_a, m_cluster_index_b,
- MatrixPredicate.ExteriorBoundary);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorBoundary, 0);
- }
-
- return bRelationKnown;
+ 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;
+ boolean bRelationKnown = true;
- if (m_perform_predicates[MatrixPredicate.InteriorInterior]) {
- interiorAreaInteriorPoint_(cluster, id_a);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorInterior, 0);
- }
+ if (m_perform_predicates[MatrixPredicate.InteriorInterior])
+ {
+ interiorAreaInteriorPoint_(cluster, id_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorInterior);
+ }
- if (m_perform_predicates[MatrixPredicate.BoundaryInterior]) {
- boundaryAreaInteriorPoint_(cluster, id_a, id_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryInterior, 0);
- }
+ if (m_perform_predicates[MatrixPredicate.InteriorExterior])
+ {
+ interiorAreaExteriorPoint_(cluster, id_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.InteriorExterior);
+ }
- if (m_perform_predicates[MatrixPredicate.ExteriorInterior]) {
- exteriorAreaInteriorPoint_(cluster, id_a);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorInterior, 0);
- }
+ if (m_perform_predicates[MatrixPredicate.BoundaryInterior])
+ {
+ boundaryAreaInteriorPoint_(cluster, id_a, id_b);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryInterior);
+ }
- return bRelationKnown;
+ 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;
+ boolean bRelationKnown = true;
- if (m_perform_predicates[MatrixPredicate.InteriorInterior]) {
- interiorLineInteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorInterior, 0);
- }
+ 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.BoundaryInterior]) {
- boundaryLineInteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryInterior, 0);
- }
+ 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.BoundaryExterior]) {
- boundaryLineExteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.BoundaryExterior, 0);
- }
+ 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.ExteriorInterior]) {
- exteriorLineInteriorPoint_(cluster, id_a, id_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.ExteriorInterior, 0);
- }
+ if (m_perform_predicates[MatrixPredicate.BoundaryExterior])
+ {
+ boundaryLineExteriorPoint_(cluster, id_a, id_b, m_cluster_index_a);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.BoundaryExterior);
+ }
- return bRelationKnown;
+ 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;
+ boolean bRelationKnown = true;
- if (m_perform_predicates[MatrixPredicate.InteriorInterior]) {
- interiorPointInteriorPoint_(cluster, id_a, id_b);
- bRelationKnown &= isPredicateKnown_(
- MatrixPredicate.InteriorInterior, 0);
- }
+ 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, 0);
- }
+ 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, 0);
- }
+ if (m_perform_predicates[MatrixPredicate.ExteriorInterior])
+ {
+ interiorPointExteriorPoint_(cluster, id_b, id_a, MatrixPredicate.ExteriorInterior);
+ bRelationKnown &= isPredicateKnown_(MatrixPredicate.ExteriorInterior);
+ }
- return bRelationKnown;
+ return bRelationKnown;
}
// Relational predicate to determine if the interior of area A intersects
@@ -1766,6 +2208,19 @@ private void interiorAreaBoundaryLine_(int half_edge, int id_a, int id_b,
}
}
+ 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,
@@ -2047,6 +2502,19 @@ private void interiorAreaInteriorPoint_(int cluster, int id_a) {
}
}
+ 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) {
@@ -2060,6 +2528,19 @@ private void boundaryAreaInteriorPoint_(int cluster, int id_a, int id_b) {
}
}
+ 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) {
@@ -2097,6 +2578,34 @@ private void interiorLineInteriorPoint_(int cluster, int id_a, int id_b,
}
}
+ 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,
@@ -2189,6 +2698,27 @@ private void computeMatrixTopoGraphHalfEdges_(int geometry_a, int geometry_b) {
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 {
@@ -2199,7 +2729,7 @@ private void computeMatrixTopoGraphHalfEdges_(int geometry_a, int geometry_b) {
if (visited != 1) {
do {
// Invoke relational predicates
- switch (m_predicates) {
+ switch (m_predicates_half_edge) {
case Predicates.AreaAreaPredicates:
bRelationKnown = areaAreaPredicates_(half_edge,
id_a, id_b);
@@ -2254,7 +2784,7 @@ private void computeMatrixTopoGraphClusters_(int geometry_a, int geometry_b) {
for (int cluster = m_topo_graph.getFirstCluster(); cluster != -1; cluster = m_topo_graph
.getNextCluster(cluster)) {
// Invoke relational predicates
- switch (m_predicates) {
+ switch (m_predicates_cluster) {
case Predicates.AreaPointPredicates:
bRelationKnown = areaPointPredicates_(cluster, id_a, id_b);
break;
@@ -2290,12 +2820,13 @@ private void setEditShapeCrackAndCluster_(EditShape shape,
private void editShapeCrackAndCluster_(EditShape shape, double tolerance,
ProgressTracker progress_tracker) {
- CrackAndCluster.execute(shape, tolerance, 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);
+ Simplificator.execute(shape, geometry, -1, false, progress_tracker);
}
}
diff --git a/src/main/java/com/esri/core/geometry/RingOrientationFixer.java b/src/main/java/com/esri/core/geometry/RingOrientationFixer.java
index 970ebe3e..84fa66b5 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/Segment.java b/src/main/java/com/esri/core/geometry/Segment.java
index b80a4236..b15364a2 100644
--- a/src/main/java/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);
}
@@ -485,7 +482,7 @@ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);
- double[] newAttributes = new double[(newDescription._getTotalComponents() - 2) * 2];
+ double[] newAttributes = new double[(newDescription.getTotalComponentCount() - 2) * 2];
int old_offset0 = _getEndPointOffset(m_description, 0);
int old_offset1 = _getEndPointOffset(m_description, 1);
@@ -531,9 +528,6 @@ private void _get(int endPoint, Point outPoint) {
outPoint.assignVertexDescription(m_description);
- if (outPoint.isEmptyImpl())
- outPoint._setToDefault();
-
for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
int semantics = m_description._getSemanticsImpl(attributeIndex);
@@ -583,7 +577,7 @@ 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(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex)
@@ -626,7 +620,7 @@ else if (ordinate != 0)
}
if (m_attributes == null)
- _resizeAttributes(m_description._getTotalComponents() - 2);
+ _resizeAttributes(m_description.getTotalComponentCount() - 2);
m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex) - 2
@@ -645,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;
@@ -691,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).
@@ -711,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;
@@ -778,14 +782,14 @@ int _intersect(Segment other, Point2D[] intersectionPoints,
abstract double _calculateArea2DHelper(double xorg, double yorg);
static int _getEndPointOffset(VertexDescription vd, int endPoint) {
- return endPoint * (vd._getTotalComponents() - 2);
+ 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;
@@ -801,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.
@@ -817,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);
/**
@@ -887,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
@@ -927,8 +931,8 @@ abstract boolean _isIntersectingPoint(Point2D pt, double tolerance,
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
diff --git a/src/main/java/com/esri/core/geometry/SegmentBuffer.java b/src/main/java/com/esri/core/geometry/SegmentBuffer.java
index 17df913d..a5d85076 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/SegmentFlags.java b/src/main/java/com/esri/core/geometry/SegmentFlags.java
index ab3a37e9..7f0b5da1 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/SegmentIntersector.java b/src/main/java/com/esri/core/geometry/SegmentIntersector.java
index ba82fd2f..2bf63af3 100644
--- a/src/main/java/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.
@@ -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();
@@ -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();
diff --git a/src/main/java/com/esri/core/geometry/SegmentIterator.java b/src/main/java/com/esri/core/geometry/SegmentIterator.java
index b563ccdd..089f93d8 100644
--- a/src/main/java/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;
diff --git a/src/main/java/com/esri/core/geometry/SegmentIteratorImpl.java b/src/main/java/com/esri/core/geometry/SegmentIteratorImpl.java
index c5f97d19..03761997 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/ShapeExportFlags.java b/src/main/java/com/esri/core/geometry/ShapeExportFlags.java
index 03cc9b3f..ac04ba51 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/ShapeImportFlags.java b/src/main/java/com/esri/core/geometry/ShapeImportFlags.java
index 1b2742c9..876a983d 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/ShapeModifiers.java b/src/main/java/com/esri/core/geometry/ShapeModifiers.java
index 2206c8e9..9ba3b702 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/ShapeType.java b/src/main/java/com/esri/core/geometry/ShapeType.java
index 17efe606..5d1fafa3 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/SimpleByteBufferCursor.java b/src/main/java/com/esri/core/geometry/SimpleByteBufferCursor.java
index 5b884949..e7595439 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/SimpleGeometryCursor.java b/src/main/java/com/esri/core/geometry/SimpleGeometryCursor.java
index 5ec4034d..3c185400 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/SimpleJsonCursor.java b/src/main/java/com/esri/core/geometry/SimpleJsonCursor.java
index 188d7d4d..1af987a9 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/SimpleJsonParserCursor.java b/src/main/java/com/esri/core/geometry/SimpleJsonReaderCursor.java
similarity index 78%
rename from src/main/java/com/esri/core/geometry/SimpleJsonParserCursor.java
rename to src/main/java/com/esri/core/geometry/SimpleJsonReaderCursor.java
index 1d30235c..9a0793fc 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/SimpleMapGeometryCursor.java b/src/main/java/com/esri/core/geometry/SimpleMapGeometryCursor.java
index 6d6879ed..fb281b76 100644
--- a/src/main/java/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
index 3ca4d304..8c6d7e46 100644
--- a/src/main/java/com/esri/core/geometry/SimpleRasterizer.java
+++ b/src/main/java/com/esri/core/geometry/SimpleRasterizer.java
@@ -1,5 +1,5 @@
/*
- Copyright 2013 Esri
+ 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.
@@ -24,10 +24,14 @@
package com.esri.core.geometry;
-import java.util.ArrayList;
-import java.util.Collections;
+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.
*
@@ -38,19 +42,20 @@ public class SimpleRasterizer {
* Even odd fill rule
*/
public final static int EVEN_ODD = 0;
+
/**
* Winding fill rule
*/
public final static int WINDING = 1;
-
- public static interface ScanCallback {
+
+ public interface ScanCallback {
/**
* Rasterizer calls this method for each scan it produced
- * @param y the Y coordinate for the scan
- * @param x the X coordinate for the scan
- * @param numPxls the number of pixels in the scan
+ * @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.
*/
- public abstract void drawScan(int y, int x, int numPxls);
+ void drawScan(int[] scans, int scanCount3);
}
public SimpleRasterizer() {
@@ -68,31 +73,44 @@ public void setup(int width, int height, ScanCallback callback)
activeEdgesTable_ = null;
numEdges_ = 0;
callback_ = callback;
+ if (scanBuffer_ == null)
+ scanBuffer_ = new int[128 * 3];
+
startAddingEdges();
}
- public int getWidth() {
+ public final int getWidth() {
return width_;
}
- public int getHeight() {
+ 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 void addTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
+ 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 void addRing(double xy[]) {
+ 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]);
}
@@ -100,16 +118,33 @@ public void addRing(double xy[]) {
/**
* 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 void startAddingEdges() {
+ public final void startAddingEdges() {
if (numEdges_ > 0) {
- ySortedEdges_ = null;
+ 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;
}
@@ -120,9 +155,13 @@ public void startAddingEdges() {
/**
* Renders all edges added so far, and removes them.
- * @param fillMode
+ * 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 void renderEdges(int fillMode) {
+ public final void renderEdges(int fillMode) {
evenOdd_ = fillMode == EVEN_ODD;
for (int line = minY_; line <= maxY_; line++) {
advanceAET_();
@@ -130,10 +169,6 @@ public void renderEdges(int fillMode) {
emitScans_();
}
- numEdges_ = 0;
- if (activeEdgesTable_ != null)
- activeEdgesTable_.clear();
-
startAddingEdges();//reset for new edges
}
@@ -144,9 +179,10 @@ public void renderEdges(int fillMode) {
* @param x2
* @param y2
*/
- public void addEdge(double x1, double y1, double x2, double 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;
@@ -180,27 +216,26 @@ else if (x1 >= width_ && x2 >= width_)
y1 = 0;
}
- //We know that dxdy != 0, otherwise it would return earlier
//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) {
- //we know that dx != 0, otherwise it would return earlier
+ //from earlier logic, x2 <= width_, therefore dxdy is not 0
y1 = (width_ - x1) / dxdy + y1;
x1 = width_;
}
if (x2 < -0x7fffff) {
- //we know that dx != 0, otherwise it would return earlier
+ //from earlier logic, x1 >= -1, therefore dxdy is not 0
y2 = (0 - x1) / dxdy + y1;
x2 = 0;
}
else if (x2 > bigX) {
- //we know that dx != 0, otherwise it would return earlier
+ //from earlier logic, x1 <= width_, therefore dxdy is not 0
y2 = (width_ - x1) / dxdy + y1;
x2 = width_;
}
@@ -210,11 +245,7 @@ else if (x2 > bigX) {
if (ystart == yend)
return;
- Edge e;
- if (recycledEdges_ != null && recycledEdges_.size() > 0)
- e = recycledEdges_.remove(recycledEdges_.size() - 1);
- else
- e = new Edge();
+ Edge e = new Edge();
e.x = (long)(x1 * 4294967296.0);
e.y = ystart;
@@ -223,84 +254,233 @@ else if (x2 > bigX) {
e.dir = dir;
if (ySortedEdges_ == null) {
- ySortedEdges_ = new ArrayList>();
- ySortedEdges_.ensureCapacity(height_);
- for (int i = 0; i < height_; i++) {
- ySortedEdges_.add(null);
- }
+ ySortedEdges_ = new Edge[height_];
}
- if (ySortedEdges_.get(e.y) == null) {
- ySortedEdges_.set(e.y, new ArrayList());
- }
+ e.next = ySortedEdges_[e.y];
+ ySortedEdges_[e.y] = e;
- ySortedEdges_.get(e.y).add(e);
if (e.y < minY_)
minY_ = e.y;
if (e.ymax > maxY_)
maxY_ = e.ymax;
+
+ numEdges_++;
}
- class Edge {
+ 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 void advanceAET_() {
- if (activeEdgesTable_ != null && activeEdgesTable_.size() > 0) {
- for (int i = 0, n = activeEdgesTable_.size(); i < n; i++) {
- Edge e = activeEdgesTable_.get(i);
- e.y++;
- if (e.y == e.ymax) {
- if (recycledEdges_ == null) {
- recycledEdges_ = new ArrayList();
- }
-
- recycledEdges_.add(e);
- activeEdgesTable_.set(i, null);
- continue;
- }
+ 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;
- e.x += e.dxdy;
+ 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 void addNewEdgesToAET_(int y) {
- if (y >= ySortedEdges_.size())
+ private final void addNewEdgesToAET_(int y) {
+ if (y >= height_)
return;
-
- if (activeEdgesTable_ == null)
- activeEdgesTable_ = new ArrayList();
-
- ArrayList edgesOnLine = ySortedEdges_.get(y);
+
+ Edge edgesOnLine = ySortedEdges_[y];
if (edgesOnLine != null) {
- for (int i = 0, n = edgesOnLine.size(); i < n; i++) {
- activeEdgesTable_.add(edgesOnLine.get(i));
+ 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;
}
- edgesOnLine.clear();
+ if (activeEdgesTable_ == null)
+ activeEdgesTable_ = edgesOnLine;
}
}
- static int snap_(int x, int mi, int ma) {
+ private static int snap_(int x, int mi, int ma) {
return x < mi ? mi : x > ma ? ma : x;
}
- private void emitScans_() {
- sortAET_();
-
- if (activeEdgesTable_ == null || activeEdgesTable_.size() == 0)
+
+ private final void emitScans_() {
+ if (activeEdgesTable_ == null)
return;
int w = 0;
- Edge e0 = activeEdgesTable_.get(0);
+ Edge e0 = activeEdgesTable_;
int x0 = (int)(e0.x >> 32);
- for (int i = 1; i < activeEdgesTable_.size(); i++) {
- Edge e = activeEdgesTable_.get(i);
+ for (Edge e = e0.next; e != null; e = e.next) {
if (evenOdd_)
w ^= 1;
else
@@ -308,11 +488,17 @@ private void emitScans_() {
if (e.x > e0.x) {
int x = (int)(e.x >> 32);
- if (w == 1) {
+ if (w != 0) {
int xx0 = snap_(x0, 0, width_);
int xx = snap_(x, 0, width_);
if (xx > xx0 && xx0 < width_) {
- callback_.drawScan(e.y, xx0, xx - xx0);
+ scanBuffer_[scanPtr_++] = xx0;
+ scanBuffer_[scanPtr_++] = xx;
+ scanBuffer_[scanPtr_++] = e.y;
+ if (scanPtr_ == scanBuffer_.length) {
+ callback_.drawScan(scanBuffer_, scanPtr_);
+ scanPtr_ = 0;
+ }
}
}
@@ -322,56 +508,74 @@ private void emitScans_() {
}
}
- static class EdgeComparator implements Comparator {
+ static private class EdgeComparator implements Comparator {
@Override
public int compare(Edge o1, Edge o2) {
- if (o1 == null)
- return o2 == null ? 0 : 1;
- else if (o2 == null)
- return -1;
-
+ if (o1 == o2)
+ return 0;
+
return o1.x < o2.x ? -1 : o1.x > o2.x ? 1 : 0;
}
}
- private static EdgeComparator edgeCompare_ = new EdgeComparator();
+ private final static EdgeComparator edgeCompare_ = new EdgeComparator();
- private void sortAET_() {
- if (!checkAETIsSorted_())
+ 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)];
+
{
- Collections.sort(activeEdgesTable_, edgeCompare_);
- while (activeEdgesTable_.size() > 0 && activeEdgesTable_.get(activeEdgesTable_.size() - 1) == null)
- activeEdgesTable_.remove(activeEdgesTable_.size() - 1);
+ int i = 0;
+ for (Edge e = aet; e != null; e = e.next)
+ sortBuffer_[i++] = e;
}
- }
-
- private boolean checkAETIsSorted_() {
- if (activeEdgesTable_ == null || activeEdgesTable_.size() == 0)
- return true;
- Edge e0 = activeEdgesTable_.get(0);
- if (e0 == null)
- return false;
-
- for (int i = 1; i < activeEdgesTable_.size(); i++) {
- Edge e = activeEdgesTable_.get(i);
- if (e == null || e.x < e0.x) {
- return false;
+ if (num == 2) {
+ if (sortBuffer_[0].x > sortBuffer_[1].x) {
+ Edge tmp = sortBuffer_[0];
+ sortBuffer_[0] = sortBuffer_[1];
+ sortBuffer_[1] = tmp;
}
- e0 = e;
+ }
+ 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;
}
- return true;
+ prev.next = null;
+ return aet;
}
-
- private ArrayList recycledEdges_;
- private ArrayList activeEdgesTable_;
- private ArrayList> ySortedEdges_;
- public ScanCallback callback_;
+
+ 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/main/java/com/esri/core/geometry/Simplificator.java b/src/main/java/com/esri/core/geometry/Simplificator.java
index 955fea71..a5102528 100644
--- a/src/main/java/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,15 +33,16 @@ 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,
@@ -90,9 +91,15 @@ private void _beforeRemoveVertex(int vertex, boolean bChangePathFirst) {
}
}
- 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;
@@ -100,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);
@@ -128,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
@@ -164,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
@@ -188,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);
@@ -198,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
@@ -253,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))
@@ -262,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)
@@ -330,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)
@@ -354,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;
@@ -364,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;
@@ -396,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.
@@ -414,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,
@@ -442,120 +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;
-
- // 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;
- }
+ // Simplify polygon
+ int iRepeatNum = 0;
+ boolean bNeedRepeat = false;
- 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;
}
-
- if (vlistindex != -1)//vlistindex can be set to -1 after ProcessBunch call above
- 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 GeometryException.GeometryInternalError();
- }
+ 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.
@@ -571,11 +565,8 @@ private boolean _simplify() {
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;
}
}
@@ -583,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);
@@ -592,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);
@@ -612,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;
@@ -691,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,
@@ -711,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); // | |
@@ -743,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;
@@ -851,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) {
@@ -974,60 +927,16 @@ private void _removeAngleSortInfo(int vertex) {
}
protected Simplificator() {
- m_dbgCounter = 0;
}
public static boolean execute(EditShape shape, int geometry,
- int knownSimpleResult, boolean fixSelfTangency) {
+ 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);
- if (res == 0) {// sort equal vertices by the path ID
- int i1 = m_shape.getPathFromVertex(v1);
- int i2 = m_shape.getPathFromVertex(v2);
- res = i1 < i2 ? -1 : (i1 == i2 ? 0 : 1);
- }
-
- 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/main/java/com/esri/core/geometry/SpatialReference.java b/src/main/java/com/esri/core/geometry/SpatialReference.java
index a416c241..4c337e27 100644
--- a/src/main/java/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,14 +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.SpatialReference;
-import com.esri.core.geometry.SpatialReferenceSerializer;
-import com.esri.core.geometry.VertexDescription;
/**
* A class that represents the spatial reference for the geometry.
@@ -91,7 +87,11 @@ public static SpatialReference fromJson(JsonParser parser) throws Exception {
return fromJson(new JsonParserReader(parser));
}
- static SpatialReference fromJson(JsonReader parser) throws Exception {
+ 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;
@@ -105,34 +105,34 @@ static SpatialReference fromJson(JsonReader parser) throws Exception {
int vcs_wkid = -1;
int latestVcsWkid = -1;
String wkt = null;
- while (parser.nextToken() != JsonToken.END_OBJECT) {
+ while (parser.nextToken() != JsonReader.Token.END_OBJECT) {
String name = parser.currentString();
parser.nextToken();
if (!bFoundWkid && name.equals("wkid")) {
bFoundWkid = true;
- if (parser.currentToken() == JsonToken.VALUE_NUMBER_INT)
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
wkid = parser.currentIntValue();
} else if (!bFoundLatestWkid && name.equals("latestWkid")) {
bFoundLatestWkid = true;
- if (parser.currentToken() == JsonToken.VALUE_NUMBER_INT)
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
latestWkid = parser.currentIntValue();
} else if (!bFoundWkt && name.equals("wkt")) {
bFoundWkt = true;
- if (parser.currentToken() == JsonToken.VALUE_STRING)
+ if (parser.currentToken() == JsonReader.Token.VALUE_STRING)
wkt = parser.currentString();
} else if (!bFoundVcsWkid && name.equals("vcsWkid")) {
bFoundVcsWkid = true;
- if (parser.currentToken() == JsonToken.VALUE_NUMBER_INT)
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
vcs_wkid = parser.currentIntValue();
} else if (!bFoundLatestVcsWkid && name.equals("latestVcsWkid")) {
bFoundLatestVcsWkid = true;
- if (parser.currentToken() == JsonToken.VALUE_NUMBER_INT)
+ if (parser.currentToken() == JsonReader.Token.VALUE_NUMBER_INT)
latestVcsWkid = parser.currentIntValue();
}
}
diff --git a/src/main/java/com/esri/core/geometry/SpatialReferenceImpl.java b/src/main/java/com/esri/core/geometry/SpatialReferenceImpl.java
index 081b2b64..25158369 100644
--- a/src/main/java/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,22 +24,9 @@
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 final boolean no_projection_engine = true;
public final static int c_SULIMIT32 = 2147483645;
@@ -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/main/java/com/esri/core/geometry/SpatialReferenceSerializer.java b/src/main/java/com/esri/core/geometry/SpatialReferenceSerializer.java
index 5df978f2..0cf25e6c 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/StridedIndexTypeCollection.java b/src/main/java/com/esri/core/geometry/StridedIndexTypeCollection.java
index 785e696f..ae1f4dca 100644
--- a/src/main/java/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,13 +23,21 @@
*/
package com.esri.core.geometry;
+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
* collection of homogeneous elements that contain only integer fields (i.e.
* structs with Index_type members) Recycles the strides. Allows for constant
* time creation and deletion of an element.
*/
-final class StridedIndexTypeCollection {
+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;
@@ -273,4 +281,18 @@ private void grow_(long newsize) {
}
}
}
+
+ 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
index f859e9d8..3237e13c 100644
--- a/src/main/java/com/esri/core/geometry/StringUtils.java
+++ b/src/main/java/com/esri/core/geometry/StringUtils.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/SweepComparator.java b/src/main/java/com/esri/core/geometry/SweepComparator.java
index 9fb76798..a1f94376 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/SweepMonkierComparator.java b/src/main/java/com/esri/core/geometry/SweepMonkierComparator.java
index 6589ef64..2edeef22 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/TopoGraph.java b/src/main/java/com/esri/core/geometry/TopoGraph.java
index 0bf61cd7..5f57251c 100644
--- a/src/main/java/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.
@@ -70,6 +70,17 @@ static interface EnumInputMode {
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
@@ -990,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);
@@ -1182,6 +1200,7 @@ void sortHalfEdgesByAngle_(int inputMode) {
} while (edge != first);
if (angleSorter.size() > 1) {
+ boolean changed_order = true;
if (angleSorter.size() > 2) {
angleSorter.Sort(0, angleSorter.size(),
tgac); // std::sort(angleSorter.get_ptr(),
@@ -1191,12 +1210,16 @@ void sortHalfEdgesByAngle_(int inputMode) {
// 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
@@ -1325,7 +1348,10 @@ else if (m_tmpHalfEdgeOddEvenNumberIndex != -1) {
continue;
}
-
+ else {
+ //edges do not coincide
+ }
+
updateVertexToHalfEdgeConnection_(prevMerged, false);
prevMerged = -1;
ePrev = e;
@@ -1333,8 +1359,27 @@ else if (m_tmpHalfEdgeOddEvenNumberIndex != -1) {
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.
@@ -1582,6 +1627,7 @@ boolean removeSpikes_() {
void setEditShapeImpl_(EditShape shape, int inputMode,
AttributeStreamOfInt32 editShapeGeometries,
ProgressTracker progress_tracker, boolean bBuildChains) {
+ assert(!m_dirty_check_failed);
assert (editShapeGeometries == null || editShapeGeometries.size() > 0);
removeShape();
@@ -1723,6 +1769,17 @@ void setEditShapeImpl_(EditShape shape, int 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_(inputMode);
if (m_non_simple_result.m_reason != NonSimpleResult.Reason.NotDetermined)
return;
@@ -1847,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;
@@ -2454,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);
@@ -2469,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/main/java/com/esri/core/geometry/TopologicalOperations.java b/src/main/java/com/esri/core/geometry/TopologicalOperations.java
index 4e2b02b7..def5cebe 100644
--- a/src/main/java/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 {
@@ -88,13 +90,14 @@ void setEditShape(EditShape shape, ProgressTracker 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, m_bOGCOutput);
+ Simplificator.execute(shape, geometry, -1, m_bOGCOutput, progressTracker);
}
+
setEditShape(shape, progressTracker);
}
@@ -294,7 +297,7 @@ private int topoOperationPolygonPolygon_(int geometry_a, int geometry_b,
m_topo_graph.deleteUserIndexForHalfEdges(visitedEdges);
Simplificator.execute(shape, newGeometry,
- MultiVertexGeometryImpl.GeometryXSimple.Weak, m_bOGCOutput);
+ MultiVertexGeometryImpl.GeometryXSimple.Weak, m_bOGCOutput, null);
return newGeometry;
}
@@ -513,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, m_bOGCOutput);
+ MultiVertexGeometryImpl.GeometryXSimple.Weak, m_bOGCOutput, null);
int[] result = new int[3];// always returns size 3 result.
result[0] = newGeometryMultipoint;
@@ -1150,11 +1153,16 @@ MultiVertexGeometry planarSimplify(EditShape shape, int geom,
// complications. Need to do
// full crack and cluster.
{
- CrackAndCluster.execute(shape, tolerance, progress_tracker);
+ 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);
+ CrackAndCluster.execute(shape, tolerance, progress_tracker, true);
+ dirty_result = false;
}
+
if (!b_use_winding_rule_for_polygons
|| shape.getGeometryType(geom) == Geometry.Type.MultiPoint
.value())
@@ -1162,6 +1170,22 @@ MultiVertexGeometry planarSimplify(EditShape shape, int geom,
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
@@ -1175,9 +1199,11 @@ MultiVertexGeometry planarSimplify(EditShape shape, int geom,
.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);
@@ -1227,6 +1253,57 @@ 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();
diff --git a/src/main/java/com/esri/core/geometry/Transformation2D.java b/src/main/java/com/esri/core/geometry/Transformation2D.java
index 1d90b17c..1704628a 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/Transformation3D.java b/src/main/java/com/esri/core/geometry/Transformation3D.java
index 5f914381..cac98407 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/Treap.java b/src/main/java/com/esri/core/geometry/Treap.java
index d654fa3d..89cd6383 100644
--- a/src/main/java/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.
diff --git a/src/main/java/com/esri/core/geometry/UserCancelException.java b/src/main/java/com/esri/core/geometry/UserCancelException.java
index bf0b1f2b..d72479a1 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/VertexDescription.java b/src/main/java/com/esri/core/geometry/VertexDescription.java
index 296e2af3..07e7630b 100644
--- a/src/main/java/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,67 +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,
- };
+ 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,
- };
+ 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
}
/**
@@ -134,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.
@@ -181,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];
}
/**
@@ -249,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.
*
@@ -270,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);
}
@@ -302,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;
}
/**
@@ -323,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
@@ -373,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
index 9bec3a33..c6d69b15 100644
--- a/src/main/java/com/esri/core/geometry/VertexDescriptionDesignerImpl.java
+++ b/src/main/java/com/esri/core/geometry/VertexDescriptionDesignerImpl.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,188 +32,53 @@
* This factory class allows to describe and create a VertexDescription
* instance.
*/
-class VertexDescriptionDesignerImpl extends VertexDescription {
-
- /**
- * Designer default constructor produces XY vertex description (POSITION
- * semantics only).
- */
- public VertexDescriptionDesignerImpl() {
- super();
- m_semantics = new int[Semantics.MAXSEMANTICS];
- m_semantics[0] = Semantics.POSITION;
- m_attributeCount = 1;
-
- m_semanticsToIndexMap = new int[Semantics.MAXSEMANTICS];
-
- for (int i = 0; i < Semantics.MAXSEMANTICS; i++)
- m_semanticsToIndexMap[i] = -1;
-
- m_semanticsToIndexMap[m_semantics[0]] = 0;
-
- m_bModified = true;
- }
-
- /**
- * Creates description designer and initializes it from the given
- * description. Use this to add or remove attributes from the description.
- */
- public VertexDescriptionDesignerImpl(VertexDescription other) {
- super(other.hashCode(), other);
- m_bModified = true;
- }
-
- /**
- * Adds a new attribute to the VertexDescription.
- *
- * @param semantics
- * Attribute semantics.
- */
- public void addAttribute(int semantics) {
- if (hasAttribute(semantics))
- return;
+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;
+ }
- m_semanticsToIndexMap[semantics] = 0;// assign a value >= 0 to mark it
- // as existing
- _initMapping();
+ return getVertexDescription(mask);
}
- /**
- * Removes given attribute.
- *
- * @param semantics
- * Attribute semantics.
- */
- void removeAttribute(int semantics) {
-
- if (semantics == Semantics.POSITION)
- throw new IllegalArgumentException(
- "Position attribue cannot be removed");// not allowed to
- // remove the xy
-
- if (!hasAttribute(semantics))
- return;
+ static VertexDescription getMergedVertexDescription(
+ VertexDescription descr, int semantics) {
+ int mask = descr.m_semanticsBitArray | (1 << semantics);
+ if ((mask & descr.m_semanticsBitArray) == mask) {
+ return descr;
+ }
- m_semanticsToIndexMap[semantics] = -1;// assign a value < 0 to mark it
- // as removed
- _initMapping();
+ return getVertexDescription(mask);
}
- /**
- * Removes all attributes from the designer with exception of the POSITION
- * attribute.
- */
- public void reset() {
- m_semantics[0] = Semantics.POSITION;
- m_attributeCount = 1;
-
- for (int i : m_semanticsToIndexMap)
- m_semanticsToIndexMap[i] = -1;
-
- m_semanticsToIndexMap[m_semantics[0]] = 0;
- m_bModified = true;
- }
+ 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;
+ }
- /**
- * Returns a VertexDescription corresponding to the vertex design.
- * Note: the same instance of VertexDescription will be returned each time
- * for the same same set of attributes and attribute properties.
- * The method searches for the VertexDescription in a global hash table. If
- * found, it is returned. Else, a new instance of the VertexDescription is
- * added to the has table and returned.
- */
- public VertexDescription getDescription() {
- VertexDescriptionHash vdhash = VertexDescriptionHash.getInstance();
- VertexDescriptionDesignerImpl vdd = this;
- return vdhash.add(vdd);
+ return getVertexDescription(mask);
}
- /**
- * Returns a default VertexDescription that has X and Y coordinates only.
- */
static VertexDescription getDefaultDescriptor2D() {
- VertexDescriptionHash vdhash = VertexDescriptionHash.getInstance();
- VertexDescription vd = vdhash.getVD2D();
- return vd;
+ return VertexDescriptionHash.getInstance().getVD2D();
}
- /**
- * Returns a default VertexDescription that has X, Y, and Z coordinates only
- */
static VertexDescription getDefaultDescriptor3D() {
- VertexDescriptionHash vdhash = VertexDescriptionHash.getInstance();
- VertexDescription vd = vdhash.getVD3D();
- return vd;
- }
-
- VertexDescription _createInternal() {
- int hash = hashCode();
- VertexDescription vd = new VertexDescription(hash, this);
- return vd;
- }
-
- protected boolean m_bModified;
-
- protected void _initMapping() {
- m_attributeCount = 0;
- for (int i = 0, j = 0; i < Semantics.MAXSEMANTICS; i++) {
- if (m_semanticsToIndexMap[i] >= 0) {
- m_semantics[j] = i;
- m_semanticsToIndexMap[i] = j;
- j++;
- m_attributeCount++;
- }
- }
-
- m_bModified = true;
- }
-
- @Override
- public int hashCode() {
- if (m_bModified) {
- m_hash = calculateHashImpl();
- m_bModified = false;
- }
-
- return m_hash;
- }
-
- @Override
- public boolean equals(Object _other) {
- if (_other == null)
- return false;
- if (_other == this)
- return true;
- if (_other.getClass() != getClass())
- return false;
- VertexDescriptionDesignerImpl other = (VertexDescriptionDesignerImpl) (_other);
- if (other.getAttributeCount() != getAttributeCount())
- return false;
-
- for (int i = 0; i < m_attributeCount; i++) {
- if (m_semantics[i] != other.m_semantics[i])
- return false;
- }
- if (m_bModified != other.m_bModified)
- return false;
-
- return true;
+ return VertexDescriptionHash.getInstance().getVD3D();
}
- public boolean isDesignerFor(VertexDescription vd) {
- if (vd.getAttributeCount() != getAttributeCount())
- return false;
-
- for (int i = 0; i < m_attributeCount; i++) {
- if (m_semantics[i] != vd.m_semantics[i])
- return false;
- }
-
- return true;
- }
-
- // returns a mapping from the source attribute indices to the destination
- // attribute indices.
static int[] mapAttributes(VertexDescription src, VertexDescription dest) {
int[] srcToDst = new int[src.getAttributeCount()];
Arrays.fill(srcToDst, -1);
@@ -222,41 +87,4 @@ static int[] mapAttributes(VertexDescription src, VertexDescription dest) {
}
return srcToDst;
}
-
- static VertexDescription getMergedVertexDescription(VertexDescription src,
- int semanticsToAdd) {
- VertexDescriptionDesignerImpl vdd = new VertexDescriptionDesignerImpl(
- src);
- vdd.addAttribute(semanticsToAdd);
- return vdd.getDescription();
- }
-
- static VertexDescription getMergedVertexDescription(VertexDescription d1, VertexDescription d2) {
- VertexDescriptionDesignerImpl vdd = null;
- for (int semantics = Semantics.POSITION; semantics < Semantics.MAXSEMANTICS; semantics++) {
- if (!d1.hasAttribute(semantics) && d2.hasAttribute(semantics)) {
- if (vdd == null) {
- vdd = new VertexDescriptionDesignerImpl(d1);
- }
-
- vdd.addAttribute(semantics);
- }
- }
-
- if (vdd != null) {
- return vdd.getDescription();
- }
-
- return d1;
- }
-
- static VertexDescription removeSemanticsFromVertexDescription(
- VertexDescription src, int semanticsToRemove) {
- VertexDescriptionDesignerImpl vdd = new VertexDescriptionDesignerImpl(
- src);
- vdd.removeAttribute(semanticsToRemove);
- return vdd.getDescription();
- }
-
}
-
diff --git a/src/main/java/com/esri/core/geometry/VertexDescriptionHash.java b/src/main/java/com/esri/core/geometry/VertexDescriptionHash.java
index c9f9e137..8e12dfec 100644
--- a/src/main/java/com/esri/core/geometry/VertexDescriptionHash.java
+++ b/src/main/java/com/esri/core/geometry/VertexDescriptionHash.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,9 +25,11 @@
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
@@ -35,75 +37,45 @@
* VertexDescription instances to prevent duplicates.
*/
final class VertexDescriptionHash {
- Map> map = new HashMap>();
-
- private static VertexDescription m_vd2D;
+ HashMap m_map = new HashMap();
- private static VertexDescription m_vd3D;
+ 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() {
- VertexDescriptionDesignerImpl vdd2D = new VertexDescriptionDesignerImpl();
- add(vdd2D);
- VertexDescriptionDesignerImpl vdd3D = new VertexDescriptionDesignerImpl();
- vdd3D.addAttribute(Semantics.Z);
- add(vdd3D);
+ m_map.put(1, m_vd2D);
+ m_map.put(3, m_vd3D);
}
public static VertexDescriptionHash getInstance() {
return INSTANCE;
}
- public VertexDescription getVD2D() {
+ public final VertexDescription getVD2D() {
return m_vd2D;
}
- public VertexDescription getVD3D() {
+ public final VertexDescription getVD3D() {
return m_vd3D;
}
- synchronized public VertexDescription add(VertexDescriptionDesignerImpl vdd) {
- // Firstly quick test for 2D/3D descriptors.
- int h = vdd.hashCode();
-
- if ((m_vd2D != null) && m_vd2D.hashCode() == h) {
- if (vdd.isDesignerFor(m_vd2D))
- return m_vd2D;
- }
-
- if ((m_vd3D != null) && (m_vd3D.hashCode() == h)) {
- if (vdd.isDesignerFor(m_vd3D))
- return m_vd3D;
- }
-
- // Now search in the hash.
-
- VertexDescription vd = null;
- if (map.containsKey(h)) {
- WeakReference vdweak = map.get(h);
- vd = vdweak.get();
- if (vd == null) // GC'd VertexDescription
- map.remove(h);
- }
-
- if (vd == null) { // either not in map to begin with, or has been GC'd
- vd = vdd._createInternal();
-
- if (vd.getAttributeCount() == 1) {
- m_vd2D = vd;
- } else if ((vd.getAttributeCount() == 2)
- && (vd.getSemantics(1) == Semantics.Z)) {
- m_vd3D = vd;
- } else {
- WeakReference vdweak = new WeakReference(
- vd);
-
- map.put(h, vdweak);
+ 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;
}
-
- return vd;
}
+
}
diff --git a/src/main/java/com/esri/core/geometry/WkbByteOrder.java b/src/main/java/com/esri/core/geometry/WkbByteOrder.java
index 9f474f20..c973d82e 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/WkbExportFlags.java b/src/main/java/com/esri/core/geometry/WkbExportFlags.java
index d4637df8..115f39c7 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/WkbGeometryType.java b/src/main/java/com/esri/core/geometry/WkbGeometryType.java
index 07d142d0..20932cf9 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/WkbImportFlags.java b/src/main/java/com/esri/core/geometry/WkbImportFlags.java
index 5f1f0392..fdadc8a5 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/Wkid.java b/src/main/java/com/esri/core/geometry/Wkid.java
index 9ecf2bd7..9fd9cca0 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/Wkt.java b/src/main/java/com/esri/core/geometry/Wkt.java
index 08db42f1..a4c2a7f4 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/WktExportFlags.java b/src/main/java/com/esri/core/geometry/WktExportFlags.java
index 2756135d..c9974be5 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/WktImportFlags.java b/src/main/java/com/esri/core/geometry/WktImportFlags.java
index 9bc57d6a..d16c2d20 100644
--- a/src/main/java/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/main/java/com/esri/core/geometry/WktParser.java b/src/main/java/com/esri/core/geometry/WktParser.java
index 7e5afcb6..7f79ed5f 100644
--- a/src/main/java/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;
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCConcreteGeometryCollection.java b/src/main/java/com/esri/core/geometry/ogc/OGCConcreteGeometryCollection.java
index 4d91d7e2..66eb1310 100644
--- a/src/main/java/com/esri/core/geometry/ogc/OGCConcreteGeometryCollection.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCConcreteGeometryCollection.java
@@ -1,21 +1,79 @@
+/*
+ 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);
@@ -23,6 +81,11 @@ public OGCConcreteGeometryCollection(OGCGeometry geom, SpatialReference sr) {
esriSR = sr;
}
+ public OGCConcreteGeometryCollection(SpatialReference sr) {
+ geometries = new ArrayList();
+ esriSR = sr;
+ }
+
@Override
public int dimension() {
int maxD = 0;
@@ -74,7 +137,19 @@ public OGCGeometry geometryN(int n) {
@Override
public String geometryType() {
- return "GeometryCollection";
+ 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
@@ -147,6 +222,40 @@ public ByteBuffer asBinary() {
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;
@@ -191,6 +300,7 @@ public boolean isSimple() {
for (int i = 0, n = numGeometries(); i < n; i++)
if (!geometryN(i).isSimple())
return false;
+
return true;
}
@@ -252,7 +362,7 @@ protected boolean isConcreteGeometryCollection() {
return true;
}
- static class GeometryCursorOGC extends GeometryCursor {
+ private static class GeometryCursorOGC extends GeometryCursor {
private int m_index;
private int m_ind;
private List m_geoms;
@@ -301,8 +411,59 @@ public int getGeometryID() {
}
}
+
+ @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");
+ }
+ }
- List geometries;
+ 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_) {
@@ -314,8 +475,21 @@ public void setSpatialReference(SpatialReference esriSR_) {
}
@Override
- public OGCGeometry convertToMulti()
- {
+ 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;
}
@@ -323,4 +497,462 @@ public OGCGeometry convertToMulti()
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
index 2cad67f7..dd229e5e 100644
--- a/src/main/java/com/esri/core/geometry/ogc/OGCCurve.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCCurve.java
@@ -1,7 +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.ogc;
import com.esri.core.geometry.MultiPoint;
-import com.esri.core.geometry.Point;
public abstract class OGCCurve extends OGCGeometry {
public abstract double length();
@@ -18,6 +41,9 @@ public boolean isRing() {
@Override
public OGCGeometry boundary() {
+ if (isEmpty())
+ return new OGCMultiPoint(this.getEsriSpatialReference());
+
if (isClosed())
return new OGCMultiPoint(new MultiPoint(getEsriGeometry()
.getDescription()), esriSR);// return empty multipoint;
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCGeometry.java b/src/main/java/com/esri/core/geometry/ogc/OGCGeometry.java
index 9783bb94..a6fdeaa9 100644
--- a/src/main/java/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
+
+ 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.
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.json.JSONException;
+ 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;
@@ -93,7 +125,12 @@ public ByteBuffer asBinary() {
public String asGeoJson() {
OperatorExportToGeoJson op = (OperatorExportToGeoJson) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.ExportToGeoJson);
- return op.execute(getEsriGeometry());
+ 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());
}
/**
@@ -211,17 +248,36 @@ public boolean isMeasured() {
abstract public OGCGeometry boundary();
/**
- * OGC equals
- *
+ * OGC equals. Performs topological comparison with tolerance.
+ * This is different from equals(Object), that uses exact comparison.
*/
- public boolean equals(OGCGeometry another) {
+ 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,
@@ -233,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,
@@ -240,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,
@@ -247,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,
@@ -261,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,
@@ -268,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,
@@ -280,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,
@@ -381,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(
@@ -399,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(
@@ -409,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(
@@ -417,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(
@@ -488,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);
@@ -670,6 +800,17 @@ public void setSpatialReference(SpatialReference esriSR_) {
*/
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();
@@ -679,4 +820,51 @@ public String toString() {
return String
.format("%s: %s", this.getClass().getSimpleName(), snippet);
}
-}
\ No newline at end of file
+
+ @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
index ea0d84af..ef5a3631 100644
--- a/src/main/java/com/esri/core/geometry/ogc/OGCGeometryCollection.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCGeometryCollection.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;
public abstract class OGCGeometryCollection extends OGCGeometry {
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCLineString.java b/src/main/java/com/esri/core/geometry/ogc/OGCLineString.java
index eb3ee7bb..f044128d 100644
--- a/src/main/java/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
@@ -113,5 +151,10 @@ public OGCGeometry convertToMulti()
return new OGCMultiLineString((Polyline)multiPath, esriSR);
}
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ return this;
+ }
+
MultiPath multiPath;
}
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCLinearRing.java b/src/main/java/com/esri/core/geometry/ogc/OGCLinearRing.java
index e733f6a5..a4b67d78 100644
--- a/src/main/java/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
index 1084d3e2..9aae3bee 100644
--- a/src/main/java/com/esri/core/geometry/ogc/OGCMultiCurve.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCMultiCurve.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/OGCMultiLineString.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiLineString.java
index 2ea784a3..e0608f61 100644
--- a/src/main/java/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
@@ -82,5 +123,19 @@ 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/main/java/com/esri/core/geometry/ogc/OGCMultiPoint.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiPoint.java
index a57c3b4e..b1c70a02 100644
--- a/src/main/java/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);
}
/**
@@ -101,5 +133,19 @@ 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/main/java/com/esri/core/geometry/ogc/OGCMultiPolygon.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiPolygon.java
index 878ea168..941bc7c2 100644
--- a/src/main/java/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() {
@@ -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
@@ -96,5 +135,19 @@ 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/main/java/com/esri/core/geometry/ogc/OGCMultiSurface.java b/src/main/java/com/esri/core/geometry/ogc/OGCMultiSurface.java
index fbb71977..5a36dd0e 100644
--- a/src/main/java/com/esri/core/geometry/ogc/OGCMultiSurface.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCMultiSurface.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;
public abstract class OGCMultiSurface extends OGCGeometryCollection {
@@ -5,11 +29,6 @@ public double area() {
return getEsriGeometry().calculateArea2D();
}
- public OGCPoint centroid() {
- // TODO
- throw new UnsupportedOperationException();
- }
-
public OGCPoint pointOnSurface() {
// TODO
throw new UnsupportedOperationException();
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCPoint.java b/src/main/java/com/esri/core/geometry/ogc/OGCPoint.java
index b6a8f9e0..d0fba6e7 100644
--- a/src/main/java/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
@@ -82,6 +115,11 @@ public OGCGeometry convertToMulti()
{
return new OGCMultiPoint(point, esriSR);
}
+
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ return this;
+ }
com.esri.core.geometry.Point point;
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCPolygon.java b/src/main/java/com/esri/core/geometry/ogc/OGCPolygon.java
index 5a038d2a..4c95250a 100644
--- a/src/main/java/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++) {
@@ -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
@@ -108,5 +143,10 @@ public OGCGeometry convertToMulti()
return new OGCMultiPolygon(polygon, esriSR);
}
+ @Override
+ public OGCGeometry reduceFromMulti() {
+ return this;
+ }
+
Polygon polygon;
}
diff --git a/src/main/java/com/esri/core/geometry/ogc/OGCSurface.java b/src/main/java/com/esri/core/geometry/ogc/OGCSurface.java
index 99886778..989dfec8 100644
--- a/src/main/java/com/esri/core/geometry/ogc/OGCSurface.java
+++ b/src/main/java/com/esri/core/geometry/ogc/OGCSurface.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;
public abstract class OGCSurface extends OGCGeometry {
@@ -5,11 +29,6 @@ public double area() {
return getEsriGeometry().calculateArea2D();
}
- public OGCPoint centroid() {
- // TODO: implement me;
- throw new UnsupportedOperationException();
- }
-
public OGCPoint pointOnSurface() {
// TODO: support this (need to port OperatorLabelPoint)
throw new UnsupportedOperationException();
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/main/resources/com/esri/core/geometry/new_to_old_wkid.txt b/src/main/resources/com/esri/core/geometry/new_to_old_wkid.txt
index 7cb8d997..86477d47 100644
--- a/src/main/resources/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/main/resources/com/esri/core/geometry/pcs_id_to_tolerance.txt b/src/main/resources/com/esri/core/geometry/pcs_id_to_tolerance.txt
index f38609e5..e4386fc5 100644
--- a/src/main/resources/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/test/java/com/esri/core/geometry/GeometryUtils.java b/src/test/java/com/esri/core/geometry/GeometryUtils.java
index c1af6866..2734db7c 100644
--- a/src/test/java/com/esri/core/geometry/GeometryUtils.java
+++ b/src/test/java/com/esri/core/geometry/GeometryUtils.java
@@ -1,12 +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.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonParser;
-
public class GeometryUtils {
public static String getGeometryType(Geometry geomIn) {
// there are five types: esriGeometryPoint
@@ -29,12 +50,8 @@ public static String getGeometryType(Geometry geomIn) {
}
static Geometry getGeometryFromJSon(String jsonStr) {
- JsonFactory jf = new JsonFactory();
-
try {
- JsonParser jp = jf.createJsonParser(jsonStr);
- jp.nextToken();
- Geometry geom = GeometryEngine.jsonToGeometry(jp).getGeometry();
+ Geometry geom = GeometryEngine.jsonToGeometry(jsonStr).getGeometry();
return geom;
} catch (Exception ex) {
return null;
diff --git a/src/test/java/com/esri/core/geometry/RandomCoordinateGenerator.java b/src/test/java/com/esri/core/geometry/RandomCoordinateGenerator.java
index f50f12d7..dcaa0444 100644
--- a/src/test/java/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
index bd59cc9b..16c1d9df 100644
--- a/src/test/java/com/esri/core/geometry/TestAttributes.java
+++ b/src/test/java/com/esri/core/geometry/TestAttributes.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.*;
diff --git a/src/test/java/com/esri/core/geometry/TestBuffer.java b/src/test/java/com/esri/core/geometry/TestBuffer.java
old mode 100644
new mode 100755
index 38902f83..e60145bb
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestClip.java b/src/test/java/com/esri/core/geometry/TestClip.java
index ee8d675f..3dcca075 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestCommonMethods.java b/src/test/java/com/esri/core/geometry/TestCommonMethods.java
index 420718d4..9b937d4b 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestContains.java b/src/test/java/com/esri/core/geometry/TestContains.java
index 71c811e9..d6da4af7 100644
--- a/src/test/java/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
index 72b6198a..ee9c764e 100644
--- a/src/test/java/com/esri/core/geometry/TestConvexHull.java
+++ b/src/test/java/com/esri/core/geometry/TestConvexHull.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 TestConvexHull extends TestCase {
@Override
protected void setUp() throws Exception {
@@ -14,12 +40,45 @@ 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);
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.DensifyByLength);
{
Polygon polygon = new Polygon();
@@ -38,7 +97,7 @@ public static void testDegenerate() {
polygon.lineTo(3, 0);
Polygon densified = (Polygon) (densify.execute(polygon, .5, null));
- Polygon convex_hull = (Polygon) (bounding.execute(densified, null));
+ Polyline convex_hull = (Polyline) (bounding.execute(densified, null));
assertTrue(bounding.isConvex(convex_hull, null));
assertTrue(convex_hull.calculateArea2D() == 0.0);
@@ -232,21 +291,19 @@ public static void testDegenerate() {
mpoint.add(4, 4);
mpoint.add(4, 4);
- Polygon convex_hull = (Polygon) (bounding.execute(mpoint, null));
- assertTrue(convex_hull.getPointCount() == 2);
+ 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);
- MultiPoint convex_hull = (MultiPoint) (bounding.execute(mpoint,
- null));
- assertTrue(convex_hull.getPointCount() == 1);
+ Point convex_hull = (Point) bounding.execute(mpoint, null);
assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(convex_hull == mpoint);
+ assertTrue(convex_hull.getXY().equals(Point2D.construct(4, 4)));
}
{
@@ -254,7 +311,7 @@ public static void testDegenerate() {
mpoint.add(4, 4);
mpoint.add(4, 5);
- Polyline convex_hull = (Polyline) (bounding.execute(mpoint, null));
+ 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);
@@ -265,7 +322,7 @@ public static void testDegenerate() {
line.setStartXY(0, 0);
line.setEndXY(0, 1);
- Polyline convex_hull = (Polyline) (bounding.execute(line, null));
+ 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);
@@ -276,7 +333,7 @@ public static void testDegenerate() {
polyline.startPath(0, 0);
polyline.lineTo(0, 1);
- Polyline convex_hull = (Polyline) (bounding.execute(polyline, null));
+ Polyline convex_hull = (Polyline) bounding.execute(polyline, null);
assertTrue(convex_hull.getPointCount() == 2);
assertTrue(bounding.isConvex(convex_hull, null));
assertTrue(polyline == convex_hull);
@@ -285,23 +342,81 @@ public static void testDegenerate() {
{
Envelope env = new Envelope(0, 0, 10, 10);
+ assertTrue(OperatorConvexHull.local().isConvex(env, null));
- Envelope convex_hull = (Envelope) (bounding.execute(env, null));
+ Polygon convex_hull = (Polygon) bounding.execute(env, null);
assertTrue(bounding.isConvex(convex_hull, null));
- assertTrue(env == convex_hull);
+ 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);
+ 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);
@@ -330,9 +445,13 @@ public static void testSquare() {
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));
+ Polygon differenced = (Polygon) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
assertTrue(differenced.isEmpty());
assertTrue(bounding.isConvex(convex_hull, null));
@@ -340,32 +459,23 @@ public static void testSquare() {
@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);
+ 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 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));
+ 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 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));
+ Polygon differenced = (Polygon) (difference.execute(densified, convex_hull, SpatialReference.create(4326), null));
assertTrue(differenced.isEmpty());
assertTrue(bounding.isConvex(convex_hull, null));
}
@@ -376,196 +486,144 @@ public static void testPolygons() {
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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ 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 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));
+ Polygon differenced = (Polygon) (difference.execute(polygon, convex_hull, SpatialReference.create(4326), null));
assertTrue(differenced.isEmpty());
assertTrue(bounding.isConvex(convex_hull, null));
}
@@ -573,14 +631,10 @@ public static void testPolygons() {
@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);
+ 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();
@@ -591,9 +645,8 @@ public static void testPolylines() {
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));
+ 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));
}
@@ -608,11 +661,9 @@ public static void testPolylines() {
polyline.lineTo(170, 45);
polyline.lineTo(225, 65);
- Polyline densified = (Polyline) (densify.execute(polyline, 10.0,
- null));
+ 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);
+ boolean bcontains = contains.execute(convex_hull, densified, SpatialReference.create(4326), null);
assertTrue(bcontains);
assertTrue(bounding.isConvex(convex_hull, null));
@@ -621,46 +672,33 @@ public static void testPolylines() {
@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());
+ 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));
+ 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 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));
+ 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 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));
+ Polygon differenced = (Polygon) (difference.execute(shape, convex_hull, SpatialReference.create(4326), null));
assertTrue(differenced.isEmpty());
assertTrue(bounding.isConvex(convex_hull, null));
}
@@ -725,10 +763,8 @@ public static void testNonSimpleShape() {
@Test
public static void testStar() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
- OperatorDensifyByLength densify = (OperatorDensifyByLength) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.DensifyByLength);
+ 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);
@@ -797,8 +833,7 @@ public static void testPointsArray() {
@Test
public static void testMergeCursor() {
- OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.ConvexHull);
+ OperatorConvexHull bounding = (OperatorConvexHull) OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ConvexHull);
Polygon geom1 = new Polygon();
Polygon geom2 = new Polygon();
@@ -890,7 +925,7 @@ public void testHullTickTock() {
Polygon geom1 = new Polygon();
Polygon geom2 = new Polygon();
Point geom3 = new Point();
- Line geom4= new Line();
+ Line geom4 = new Line();
Envelope geom5 = new Envelope();
MultiPoint geom6 = new MultiPoint();
@@ -943,7 +978,7 @@ public void testHullTickTock() {
ticktock.tock();
// Get the result
Geometry result = ticktock.next();
- Polygon convex_hull = (Polygon)result;
+ Polygon convex_hull = (Polygon) result;
assertTrue(OperatorConvexHull.local().isConvex(convex_hull, null));
Point2D p1 = convex_hull.getXY(0);
@@ -960,4 +995,78 @@ public void testHullTickTock() {
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/src/test/java/com/esri/core/geometry/TestCut.java b/src/test/java/com/esri/core/geometry/TestCut.java
index f67a4d1f..a388ff01 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestDifference.java b/src/test/java/com/esri/core/geometry/TestDifference.java
index ca7bc3d4..2ea73ffc 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestDistance.java b/src/test/java/com/esri/core/geometry/TestDistance.java
index b531bb17..50399967 100644
--- a/src/test/java/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 {
@@ -146,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/src/test/java/com/esri/core/geometry/TestEditShape.java b/src/test/java/com/esri/core/geometry/TestEditShape.java
index 94bd5fb2..95b5ea30 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestEnvelope2DIntersector.java b/src/test/java/com/esri/core/geometry/TestEnvelope2DIntersector.java
index b7bc7d2e..2f33fadb 100644
--- a/src/test/java/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;
diff --git a/src/test/java/com/esri/core/geometry/TestEquals.java b/src/test/java/com/esri/core/geometry/TestEquals.java
index a42abf30..90ed71a0 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestFailed.java b/src/test/java/com/esri/core/geometry/TestFailed.java
index 9c7a915d..05bede19 100644
--- a/src/test/java/com/esri/core/geometry/TestFailed.java
+++ b/src/test/java/com/esri/core/geometry/TestFailed.java
@@ -1,64 +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) {
- 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/src/test/java/com/esri/core/geometry/TestGeneralize.java b/src/test/java/com/esri/core/geometry/TestGeneralize.java
index c7316e74..34d497e4 100644
--- a/src/test/java/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
index d377e6f6..93185af9 100644
--- a/src/test/java/com/esri/core/geometry/TestGeodetic.java
+++ b/src/test/java/com/esri/core/geometry/TestGeodetic.java
@@ -1,72 +1,129 @@
-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);
- */
- }
-
}
+/*
+ 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
index 80099069..83271d5b 100644
--- a/src/test/java/com/esri/core/geometry/TestGeomToGeoJson.java
+++ b/src/test/java/com/esri/core/geometry/TestGeomToGeoJson.java
@@ -3,7 +3,7 @@
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
+ 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,
@@ -22,340 +22,487 @@
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 com.esri.core.geometry.ogc.*;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
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;
+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.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);
- }
+ 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/src/test/java/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java b/src/test/java/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
index 2de57b43..1a0bf432 100644
--- a/src/test/java/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
+++ b/src/test/java/com/esri/core/geometry/TestGeomToJSonExportSRFromWkiOrWkt_CR181369.java
@@ -1,566 +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);
- }
-
- 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,\"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.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;
- }
-
- }
-
- {
- 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
- .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,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
- .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,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
- .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,\"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.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;
- 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/src/test/java/com/esri/core/geometry/TestImportExport.java b/src/test/java/com/esri/core/geometry/TestImportExport.java
index 99adee7a..73faed01 100644
--- a/src/test/java/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, 70 80 7, 80 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, 60 90 7, 90 90 7, 60 60 7), (70 70 7, 70 80 7, 80 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/src/test/java/com/esri/core/geometry/TestInterpolateAttributes.java b/src/test/java/com/esri/core/geometry/TestInterpolateAttributes.java
index de462a02..f20f3063 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestIntersect2.java b/src/test/java/com/esri/core/geometry/TestIntersect2.java
index 8bdcd3c8..36860635 100644
--- a/src/test/java/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;
diff --git a/src/test/java/com/esri/core/geometry/TestIntersection.java b/src/test/java/com/esri/core/geometry/TestIntersection.java
index ab7dd9f0..eb6a2a73 100644
--- a/src/test/java/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 {
@@ -1038,4 +1065,47 @@ public void testIntersectionIssue2() {
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/src/test/java/com/esri/core/geometry/TestIntervalTree.java b/src/test/java/com/esri/core/geometry/TestIntervalTree.java
index 0b12d678..4c0cde97 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestJSonGeometry.java b/src/test/java/com/esri/core/geometry/TestJSonGeometry.java
index 571a103e..62342524 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java b/src/test/java/com/esri/core/geometry/TestJSonToGeomFromWkiOrWkt_CR177613.java
index 243f7c26..a6ac4d96 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestJsonParser.java b/src/test/java/com/esri/core/geometry/TestJsonParser.java
index a2214e5e..96f6343c 100644
--- a/src/test/java/com/esri/core/geometry/TestJsonParser.java
+++ b/src/test/java/com/esri/core/geometry/TestJsonParser.java
@@ -1,664 +1,575 @@
-package com.esri.core.geometry;
-
-import java.util.Hashtable;
-import java.io.IOException;
-import java.util.Map;
-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.json.JSONObject;
-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());
- 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);
- }
-}
+/*
+ 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/src/test/java/com/esri/core/geometry/TestMathUtils.java b/src/test/java/com/esri/core/geometry/TestMathUtils.java
index 0d41a739..c6d39735 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestMultiPoint.java b/src/test/java/com/esri/core/geometry/TestMultiPoint.java
index b5b7d534..cd8e8d70 100644
--- a/src/test/java/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;
diff --git a/src/test/java/com/esri/core/geometry/TestOGC.java b/src/test/java/com/esri/core/geometry/TestOGC.java
index dcca0c3a..b68f2fcc 100644
--- a/src/test/java/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;
@@ -13,8 +37,6 @@
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;
@@ -40,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();
@@ -48,7 +72,7 @@ public void testPoint() {
}
@Test
- public void testPolygon() {
+ 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"));
@@ -57,21 +81,41 @@ public void testPolygon() {
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);
+ }
}
@Test
- public void testGeometryCollection() throws JSONException {
+ 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"));
@@ -139,6 +183,10 @@ 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());
}
@@ -768,7 +816,7 @@ public void testIsectTria1() {
}
@Test
- public void testIsectTriaJson1() throws JsonParseException, IOException {
+ 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);
@@ -833,15 +881,7 @@ public void testMultiPointSinglePoint() {
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)))"));
}
@@ -868,7 +908,7 @@ public void testMultiPolygonArea() {
}
@Test
- public void testPolylineSimplifyIssueGithub52() throws JsonParseException, IOException {
+ 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);
@@ -885,4 +925,135 @@ public void testPolylineSimplifyIssueGithub52() throws JsonParseException, IOExc
}
}
+ @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/src/test/java/com/esri/core/geometry/TestOffset.java b/src/test/java/com/esri/core/geometry/TestOffset.java
index 1bd18b9a..385e3504 100644
--- a/src/test/java/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;
diff --git a/src/test/java/com/esri/core/geometry/TestPoint.java b/src/test/java/com/esri/core/geometry/TestPoint.java
index df53b170..c30f612f 100644
--- a/src/test/java/com/esri/core/geometry/TestPoint.java
+++ b/src/test/java/com/esri/core/geometry/TestPoint.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;
@@ -21,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
@@ -165,5 +217,21 @@ public void testEnvelope2D_corners() {
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/src/test/java/com/esri/core/geometry/TestPolygon.java b/src/test/java/com/esri/core/geometry/TestPolygon.java
index 22d9617c..2c4b0b4f 100644
--- a/src/test/java/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);
@@ -1074,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));
@@ -1138,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/src/test/java/com/esri/core/geometry/TestPolygonUtils.java b/src/test/java/com/esri/core/geometry/TestPolygonUtils.java
index 16bc5215..2967d2f7 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/TestProximity2D.java b/src/test/java/com/esri/core/geometry/TestProximity2D.java
index f06c8ce9..9f6cd184 100644
--- a/src/test/java/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;
diff --git a/src/test/java/com/esri/core/geometry/TestQuadTree.java b/src/test/java/com/esri/core/geometry/TestQuadTree.java
index 3836ec13..9c4800ad 100644
--- a/src/test/java/com/esri/core/geometry/TestQuadTree.java
+++ b/src/test/java/com/esri/core/geometry/TestQuadTree.java
@@ -1,6 +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.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 {
@@ -16,11 +49,24 @@ protected void tearDown() throws Exception {
@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);
+ QuadTree quadtree = buildQuadTree_(polylineImpl, false);
Line queryline = new Line(34, 9, 66, 46);
QuadTree.QuadTreeIterator qtIter = quadtree.getIterator();
@@ -34,12 +80,12 @@ public static void test1() {
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);
+ qtIter.resetIterator(queryline, 0.0);
element_handle = qtIter.next();
while (element_handle > 0) {
@@ -49,6 +95,336 @@ public static void test1() {
}
}
+ @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();
@@ -78,6 +454,7 @@ public static void test2() {
assertTrue(count == 10000);
}
+
public static Polyline makePolyline() {
Polyline poly = new Polyline();
@@ -116,10 +493,10 @@ public static Polyline makePolyline() {
return poly;
}
- static QuadTree buildQuadTree_(MultiPathImpl multipathImpl) {
+ static QuadTree buildQuadTree_(MultiPathImpl multipathImpl, boolean bStoreDuplicates) {
Envelope2D extent = new Envelope2D();
multipathImpl.queryEnvelope2D(extent);
- QuadTree quadTree = new QuadTree(extent, 8);
+ QuadTree quadTree = new QuadTree(extent, 8, bStoreDuplicates);
int hint_index = -1;
Envelope2D boundingbox = new Envelope2D();
SegmentIteratorImpl seg_iter = multipathImpl.querySegmentIterator();
diff --git a/src/test/java/com/esri/core/geometry/TestRasterizedGeometry2D.java b/src/test/java/com/esri/core/geometry/TestRasterizedGeometry2D.java
index a96528ca..c8c835be 100644
--- a/src/test/java/com/esri/core/geometry/TestRasterizedGeometry2D.java
+++ b/src/test/java/com/esri/core/geometry/TestRasterizedGeometry2D.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;
import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
@@ -130,5 +155,23 @@ public void test() {
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/src/test/java/com/esri/core/geometry/TestRelation.java b/src/test/java/com/esri/core/geometry/TestRelation.java
index 613f8b13..4ecbf514 100644
--- a/src/test/java/com/esri/core/geometry/TestRelation.java
+++ b/src/test/java/com/esri/core/geometry/TestRelation.java
@@ -1,5 +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 java.io.IOException;
+
import junit.framework.TestCase;
import org.junit.Test;
@@ -19,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);
@@ -132,7 +158,7 @@ public static void testCreation() {
}
@Test
- public static void testOperatorDisjoint() {
+ public void testOperatorDisjoint() {
{
OperatorFactoryLocal projEnv = OperatorFactoryLocal.getInstance();
SpatialReference inputSR = SpatialReference.create(3857);
@@ -191,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));
@@ -219,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));
@@ -247,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));
@@ -270,7 +296,7 @@ public static void testTouchPolygonPolygon() {
}
@Test
- public static void testContainsFailureCR186456() {
+ public void testContainsFailureCR186456() {
{
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
@@ -283,7 +309,7 @@ public static void testContainsFailureCR186456() {
}
@Test
- public static void testWithin() {
+ public void testWithin() {
{
OperatorWithin op = (OperatorWithin) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Within));
@@ -364,7 +390,7 @@ public static void testWithin() {
}
@Test
- public static void testContains() {
+ public void testContains() {
{
OperatorContains op = (OperatorContains) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Contains));
@@ -444,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));
@@ -618,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);
@@ -697,7 +723,7 @@ public static void testPolygonPolygonEquals() {
}
@Test
- public static void testMultiPointMultiPointEquals() {
+ public void testMultiPointMultiPointEquals() {
OperatorEquals equals = (OperatorEquals) OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Equals);
SpatialReference sr = SpatialReference.create(102100);
@@ -738,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
@@ -780,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
@@ -843,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);
@@ -916,10 +942,61 @@ public static void testPolygonPolygonDisjoint() {
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);
@@ -970,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);
@@ -1031,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);
@@ -1077,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
@@ -1136,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);
@@ -1178,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
@@ -1226,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);
@@ -1275,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);
@@ -1316,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);
@@ -1348,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);
@@ -1430,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);
@@ -1495,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);
@@ -1640,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);
@@ -1699,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);
@@ -1752,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);
@@ -1778,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);
@@ -1855,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);
@@ -1888,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);
@@ -1940,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);
@@ -2007,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);
@@ -2065,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);
@@ -2120,10 +2197,140 @@ public static void testPolygonPolygonWithin() {
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
@@ -2191,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);
@@ -2239,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);
@@ -2270,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);
@@ -2324,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);
@@ -2414,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
@@ -2866,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
@@ -3254,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
@@ -3583,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
@@ -3722,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
@@ -4350,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));
@@ -4425,259 +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);
+ polyline2.startPath(1, 1);
+ polyline2.lineTo(2, 0);
- scl = "FF1FT01T2";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ 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 = "****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 = "****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*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 = "****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*001*T";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- scl = "T********";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "T********";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- scl = "F********";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "F********";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline1.setEmpty();
- polyline2.setEmpty();
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- polyline1.startPath(0, 0);
- polyline1.lineTo(1, 0);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(1, 0);
- polyline2.startPath(0, 0);
- polyline2.lineTo(1, 0);
+ polyline2.startPath(0, 0);
+ polyline2.lineTo(1, 0);
- scl = "1FFFTFFFT";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "1FFFTFFFT";
+ 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*T*T****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- scl = "1T**T****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "1T**T****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- polyline1.setEmpty();
- polyline2.setEmpty();
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- polyline1.startPath(0, 0);
- polyline1.lineTo(0.5, 0.5);
- polyline1.lineTo(1, 1);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(0.5, 0.5);
+ polyline1.lineTo(1, 1);
- polyline2.startPath(1, 0);
- polyline2.lineTo(0.5, 0.5);
- polyline2.lineTo(0, 1);
+ polyline2.startPath(1, 0);
+ polyline2.lineTo(0.5, 0.5);
+ polyline2.lineTo(0, 1);
- scl = "0F1FFTT0T";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "0F1FFTT0T";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- scl = "*T*******";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "*T*******";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- scl = "*F*F*****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "*F*F*****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline1.setEmpty();
- polyline2.setEmpty();
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- polyline1.startPath(0, 0);
- polyline1.lineTo(1, 0);
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(1, 0);
- polyline2.startPath(1, -1);
- polyline2.lineTo(1, 1);
+ polyline2.startPath(1, -1);
+ polyline2.lineTo(1, 1);
- scl = "FT1TF01TT";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(!res);
+ scl = "FT1TF01TT";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(!res);
- scl = "***T*****";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ scl = "***T*****";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- polyline1.setEmpty();
- polyline2.setEmpty();
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- polyline1.startPath(0, 0);
- polyline1.lineTo(0, 20);
- polyline1.lineTo(20, 20);
- polyline1.lineTo(20, 0);
- polyline1.lineTo(0, 0); // has no boundary
+ polyline1.startPath(0, 0);
+ polyline1.lineTo(0, 20);
+ polyline1.lineTo(20, 20);
+ polyline1.lineTo(20, 0);
+ polyline1.lineTo(0, 0); // has no boundary
- polyline2.startPath(3, 3);
- polyline2.lineTo(5, 5);
+ polyline2.startPath(3, 3);
+ polyline2.lineTo(5, 5);
+
+ op.accelerateGeometry(polyline1, sr, Geometry.GeometryAccelerationDegree.enumHot);
- op.accelerateGeometry(polyline1, sr,
- Geometry.GeometryAccelerationDegree.enumHot);
+ scl = "FF1FFF102";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- scl = "FF1FFF102";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ polyline1.setEmpty();
+ polyline2.setEmpty();
- polyline1.setEmpty();
- polyline2.setEmpty();
+ polyline1.startPath(4, 0);
+ polyline1.lineTo(0, 4);
+ polyline1.lineTo(4, 8);
+ polyline1.lineTo(8, 4);
- polyline1.startPath(4, 0);
- polyline1.lineTo(0, 4);
- polyline1.lineTo(4, 8);
- polyline1.lineTo(8, 4);
+ polyline2.startPath(8, 1);
+ polyline2.lineTo(8, 2);
- polyline2.startPath(8, 1);
- polyline2.lineTo(8, 2);
+ op.accelerateGeometry(polyline1, sr, GeometryAccelerationDegree.enumHot);
- op.accelerateGeometry(polyline1, sr,
- Geometry.GeometryAccelerationDegree.enumHot);
+ scl = "FF1FF0102";
+ res = op.execute(polyline1, polyline2, sr, scl, null);
+ assertTrue(res);
- scl = "FF1FF0102";
- res = op.execute(polyline1, polyline2, sr, scl, null);
- assertTrue(res);
+ 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);
}
@Test
- public static void testPolygonPolylineRelate() {
- OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
- .getInstance().getOperator(Operator.Type.Relate));
- 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 = "FF*FT****";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
-
- polyline2.setEmpty();
- polyline2.startPath(0, 0);
- polyline2.lineTo(10, 0);
-
- scl = "***1*1FF*";
- res = op.execute(polygon1, polyline2, sr, scl, null);
- assertTrue(res);
-
- scl = "F**1*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 = "TT*******";
- 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 = "1T*0F*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,
- Geometry.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);
+ 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);
@@ -4724,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);
@@ -4751,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);
@@ -4775,10 +5109,22 @@ public static void testPointPointRelate() {
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);
@@ -4858,7 +5204,7 @@ public static void testPolygonMultiPointRelate() {
}
@Test
- public static void testPolygonPointRelate() {
+ public void testPolygonPointRelate() {
OperatorRelate op = (OperatorRelate) (OperatorFactoryLocal
.getInstance().getOperator(Operator.Type.Relate));
SpatialReference sr = SpatialReference.create(4326);
@@ -4878,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);
@@ -4945,10 +5396,101 @@ 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 void testPolylinePointRelate()
+ {
+ OperatorRelate op = OperatorRelate.local();
+ SpatialReference sr = SpatialReference.create(4326);
+ boolean res;
+ String scl;
+
+ Polyline polyline = new Polyline();
+ Point point = new Point();
+
+ polyline.startPath(0, 2);
+ polyline.lineTo(0, 4);
+
+ point.setXY(0, 3);
+
+ scl = "0F1FF0FF2";
+ res = op.execute(polyline, point, sr, scl, null);
+ assertTrue(res);
+
+ 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();
+
+ 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 static void testCrosses_github_issue_40() {
+ 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,
@@ -4965,4 +5507,25 @@ public static void testCrosses_github_issue_40() {
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
index 289546da..5f3796a1 100644
--- a/src/test/java/com/esri/core/geometry/TestSerialization.java
+++ b/src/test/java/com/esri/core/geometry/TestSerialization.java
@@ -1,338 +1,496 @@
-package com.esri.core.geometry;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-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");
- }
- }
-
- @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");
- }
- }
-
-}
+/*
+ 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/src/test/java/com/esri/core/geometry/TestSimplify.java b/src/test/java/com/esri/core/geometry/TestSimplify.java
index b7caf8a3..944d271d 100644
--- a/src/test/java/com/esri/core/geometry/TestSimplify.java
+++ b/src/test/java/com/esri/core/geometry/TestSimplify.java
@@ -1,1329 +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() {
- //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() 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/src/test/java/com/esri/core/geometry/TestTouch.java b/src/test/java/com/esri/core/geometry/TestTouch.java
index b677ba7d..8be45c11 100644
--- a/src/test/java/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;
diff --git a/src/test/java/com/esri/core/geometry/TestTreap.java b/src/test/java/com/esri/core/geometry/TestTreap.java
index 3bd20606..e1f2b5b5 100644
--- a/src/test/java/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
index ad06dbbc..77032413 100644
--- a/src/test/java/com/esri/core/geometry/TestUnion.java
+++ b/src/test/java/com/esri/core/geometry/TestUnion.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;
@@ -16,11 +40,6 @@ protected void tearDown() throws Exception {
@Test
public static void testUnion() {
- Point pt = new Point(10, 20);
-
- 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 };
@@ -33,5 +52,129 @@ public static void testUnion() {
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
index 196e5e1e..dfbaba16 100644
--- a/src/test/java/com/esri/core/geometry/TestWKBSupport.java
+++ b/src/test/java/com/esri/core/geometry/TestWKBSupport.java
@@ -1,99 +1,119 @@
-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);
- } 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);
-
- }
-
}
+/*
+ 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/src/test/java/com/esri/core/geometry/TestWkbImportOnPostgresST.java b/src/test/java/com/esri/core/geometry/TestWkbImportOnPostgresST.java
index ccac6c5f..95c55d2b 100644
--- a/src/test/java/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/test/java/com/esri/core/geometry/TestWkid.java b/src/test/java/com/esri/core/geometry/TestWkid.java
index fc09a66c..9bac7c5b 100644
--- a/src/test/java/com/esri/core/geometry/TestWkid.java
+++ b/src/test/java/com/esri/core/geometry/TestWkid.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.*;
@@ -19,4 +43,14 @@ public void test() {
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/src/test/java/com/esri/core/geometry/TestWktParser.java b/src/test/java/com/esri/core/geometry/TestWktParser.java
index 9949e5a3..71ce5b1d 100644
--- a/src/test/java/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/src/test/java/com/esri/core/geometry/Utils.java b/src/test/java/com/esri/core/geometry/Utils.java
index 9bbe51c0..d9923281 100644
--- a/src/test/java/com/esri/core/geometry/Utils.java
+++ b/src/test/java/com/esri/core/geometry/Utils.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;
public class Utils {
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/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/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/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/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