提交 a86361cc authored 作者: Thomas Mueller's avatar Thomas Mueller

Improved Geometry processing (issue 535).

上级 d0aeb181
...@@ -18,7 +18,8 @@ Change Log ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>The collation can now be set in the database URL, even if there are data tables, <ul><li>Improved Geometry processing (issue 535).
</li><li>The collation can now be set in the database URL, even if there are data tables,
if the collection is the same as the current collation. if the collection is the same as the current collation.
</li><li>Improved Oracle compatibility for CASE WHEN and DECODE. </li><li>Improved Oracle compatibility for CASE WHEN and DECODE.
</li><li>The statement "drop all objects" did not work if a table depends on a view via a constraint. </li><li>The statement "drop all objects" did not work if a table depends on a view via a constraint.
......
...@@ -33,14 +33,27 @@ import com.vividsolutions.jts.io.WKTWriter; ...@@ -33,14 +33,27 @@ import com.vividsolutions.jts.io.WKTWriter;
public class ValueGeometry extends Value { public class ValueGeometry extends Value {
/** /**
* The value. * The value. Converted from WKB only on request as conversion from/to WKB
* cost a significant amount of cpu cycles.
*/ */
private final Geometry geometry; private Geometry geometry;
/**
* As conversion from/to WKB cost a significant amount of cpu cycles, WKB
* are kept in ValueGeometry instance
*/
private byte[] bytes;
private int hashCode;
private ValueGeometry(Geometry geometry) { private ValueGeometry(Geometry geometry) {
this.geometry = geometry; this.geometry = geometry;
} }
private ValueGeometry(byte[] bytes) {
this.bytes = bytes;
}
/** /**
* Get or create a geometry value for the given geometry. * Get or create a geometry value for the given geometry.
* *
...@@ -79,10 +92,13 @@ public class ValueGeometry extends Value { ...@@ -79,10 +92,13 @@ public class ValueGeometry extends Value {
* @return the value * @return the value
*/ */
public static ValueGeometry get(byte[] bytes) { public static ValueGeometry get(byte[] bytes) {
return (ValueGeometry) Value.cache(new ValueGeometry(fromWKB(bytes))); return (ValueGeometry) Value.cache(new ValueGeometry(bytes));
} }
public Geometry getGeometry() { public Geometry getGeometry() {
if (geometry == null && bytes != null) {
geometry = fromWKB(bytes);
}
return geometry; return geometry;
} }
...@@ -95,7 +111,7 @@ public class ValueGeometry extends Value { ...@@ -95,7 +111,7 @@ public class ValueGeometry extends Value {
*/ */
public boolean intersectsBoundingBox(ValueGeometry r) { public boolean intersectsBoundingBox(ValueGeometry r) {
// the Geometry object caches the envelope // the Geometry object caches the envelope
return geometry.getEnvelopeInternal().intersects(r.getGeometry().getEnvelopeInternal()); return getGeometry().getEnvelopeInternal().intersects(r.getGeometry().getEnvelopeInternal());
} }
/** /**
...@@ -106,7 +122,7 @@ public class ValueGeometry extends Value { ...@@ -106,7 +122,7 @@ public class ValueGeometry extends Value {
*/ */
public Value getEnvelopeUnion(ValueGeometry r) { public Value getEnvelopeUnion(ValueGeometry r) {
GeometryFactory gf = new GeometryFactory(); GeometryFactory gf = new GeometryFactory();
Envelope mergedEnvelope = new Envelope(geometry.getEnvelopeInternal()); Envelope mergedEnvelope = new Envelope(getGeometry().getEnvelopeInternal());
mergedEnvelope.expandToInclude(r.getGeometry().getEnvelopeInternal()); mergedEnvelope.expandToInclude(r.getGeometry().getEnvelopeInternal());
return get(gf.toGeometry(mergedEnvelope)); return get(gf.toGeometry(mergedEnvelope));
} }
...@@ -118,7 +134,7 @@ public class ValueGeometry extends Value { ...@@ -118,7 +134,7 @@ public class ValueGeometry extends Value {
* @return the intersection of this geometry envelope and another * @return the intersection of this geometry envelope and another
*/ */
public ValueGeometry getEnvelopeIntersection(ValueGeometry r) { public ValueGeometry getEnvelopeIntersection(ValueGeometry r) {
Envelope e1 = geometry.getEnvelopeInternal(); Envelope e1 = getGeometry().getEnvelopeInternal();
Envelope e2 = r.getGeometry().getEnvelopeInternal(); Envelope e2 = r.getGeometry().getEnvelopeInternal();
Envelope e3 = e1.intersection(e2); Envelope e3 = e1.intersection(e2);
// try to re-use the object // try to re-use the object
...@@ -143,8 +159,8 @@ public class ValueGeometry extends Value { ...@@ -143,8 +159,8 @@ public class ValueGeometry extends Value {
@Override @Override
protected int compareSecure(Value v, CompareMode mode) { protected int compareSecure(Value v, CompareMode mode) {
Geometry g = ((ValueGeometry) v).geometry; Geometry g = ((ValueGeometry) v).getGeometry();
return geometry.compareTo(g); return getGeometry().compareTo(g);
} }
@Override @Override
...@@ -154,17 +170,20 @@ public class ValueGeometry extends Value { ...@@ -154,17 +170,20 @@ public class ValueGeometry extends Value {
@Override @Override
public long getPrecision() { public long getPrecision() {
return toWKT().length(); return 0;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return geometry.hashCode(); if (hashCode == 0) {
hashCode = Arrays.hashCode(toWKB());
}
return hashCode;
} }
@Override @Override
public Object getObject() { public Object getObject() {
return geometry; return getGeometry();
} }
@Override @Override
...@@ -179,7 +198,7 @@ public class ValueGeometry extends Value { ...@@ -179,7 +198,7 @@ public class ValueGeometry extends Value {
@Override @Override
public void set(PreparedStatement prep, int parameterIndex) throws SQLException { public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
prep.setObject(parameterIndex, geometry); prep.setObject(parameterIndex, getGeometry());
} }
@Override @Override
...@@ -205,7 +224,7 @@ public class ValueGeometry extends Value { ...@@ -205,7 +224,7 @@ public class ValueGeometry extends Value {
* @return the well-known-text * @return the well-known-text
*/ */
public String toWKT() { public String toWKT() {
return new WKTWriter().write(geometry); return new WKTWriter().write(getGeometry());
} }
/** /**
...@@ -214,7 +233,10 @@ public class ValueGeometry extends Value { ...@@ -214,7 +233,10 @@ public class ValueGeometry extends Value {
* @return the well-known-binary * @return the well-known-binary
*/ */
public byte[] toWKB() { public byte[] toWKB() {
return toWKB(geometry); if (bytes != null) {
return bytes;
}
return toWKB(getGeometry());
} }
private static byte[] toWKB(Geometry geometry) { private static byte[] toWKB(Geometry geometry) {
......
...@@ -63,10 +63,22 @@ public class TestSpatial extends TestBase { ...@@ -63,10 +63,22 @@ public class TestSpatial extends TestBase {
testWKB(); testWKB();
testValueConversion(); testValueConversion();
testEquals(); testEquals();
testHashCode();
deleteDb("spatial"); deleteDb("spatial");
} }
} }
private void testHashCode() {
ValueGeometry geomA = ValueGeometry
.get("POLYGON ((67 13 6, 67 18 5, 59 18 4, 59 13 6, 67 13 6))");
ValueGeometry geomB = ValueGeometry
.get("POLYGON ((67 13 6, 67 18 5, 59 18 4, 59 13 6, 67 13 6))");
ValueGeometry geomC = ValueGeometry
.get("POLYGON ((67 13 6, 67 18 5, 59 18 4, 59 13 5, 67 13 6))");
assertEquals(geomA.hashCode(), geomB.hashCode());
assertFalse(geomA.hashCode() == geomC.hashCode());
}
private void testSpatialValues() throws SQLException { private void testSpatialValues() throws SQLException {
deleteDb("spatial"); deleteDb("spatial");
Connection conn = getConnection("spatial"); Connection conn = getConnection("spatial");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论