提交 3f58272d authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Use own utilities instead of JTS

上级 9ca18311
...@@ -14,18 +14,17 @@ import org.h2.index.Index; ...@@ -14,18 +14,17 @@ import org.h2.index.Index;
import org.h2.mvstore.db.MVSpatialIndex; import org.h2.mvstore.db.MVSpatialIndex;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.geometry.GeometryUtils;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueGeometry; import org.h2.value.ValueGeometry;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.GeometryFactory;
/** /**
* Data stored while calculating an aggregate. * Data stored while calculating an aggregate.
*/ */
class AggregateDataEnvelope extends AggregateData { class AggregateDataEnvelope extends AggregateData {
private Envelope envelope; private double[] envelope;
/** /**
* Get the index (if any) for the column specified in the geometry * Get the index (if any) for the column specified in the geometry
...@@ -62,18 +61,15 @@ class AggregateDataEnvelope extends AggregateData { ...@@ -62,18 +61,15 @@ class AggregateDataEnvelope extends AggregateData {
if (v == ValueNull.INSTANCE) { if (v == ValueNull.INSTANCE) {
return; return;
} }
if (envelope == null) { envelope = GeometryUtils.union(envelope, ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getEnvelopeNoCopy());
envelope = new Envelope();
}
envelope.expandToInclude(((ValueGeometry) v.convertTo(Value.GEOMETRY)).getEnvelopeNoCopy());
} }
@Override @Override
Value getValue(Database database, int dataType, boolean distinct) { Value getValue(Database database, int dataType, boolean distinct) {
if (envelope == null || envelope.isNull()) { if (envelope == null) {
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
} }
return ValueGeometry.getFromGeometry(new GeometryFactory().toGeometry(envelope)); return ValueGeometry.get(GeometryUtils.envelope2wkb(envelope));
} }
} }
...@@ -5,6 +5,11 @@ ...@@ -5,6 +5,11 @@
*/ */
package org.h2.index; package org.h2.index;
import static org.h2.util.geometry.GeometryUtils.MAX_X;
import static org.h2.util.geometry.GeometryUtils.MAX_Y;
import static org.h2.util.geometry.GeometryUtils.MIN_X;
import static org.h2.util.geometry.GeometryUtils.MIN_Y;
import java.util.Iterator; import java.util.Iterator;
import org.h2.command.dml.AllColumnsForPlan; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -23,7 +28,6 @@ import org.h2.table.TableFilter; ...@@ -23,7 +28,6 @@ import org.h2.table.TableFilter;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueGeometry; import org.h2.value.ValueGeometry;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.locationtech.jts.geom.Envelope;
/** /**
* This is an index based on a MVR-TreeMap. * This is an index based on a MVR-TreeMap.
...@@ -133,10 +137,9 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex { ...@@ -133,10 +137,9 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex {
if (v == ValueNull.INSTANCE) { if (v == ValueNull.INSTANCE) {
return new SpatialKey(row.getKey()); return new SpatialKey(row.getKey());
} }
Envelope env = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getEnvelopeNoCopy(); double[] env = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getEnvelopeNoCopy();
return new SpatialKey(row.getKey(), return new SpatialKey(row.getKey(),
(float) env.getMinX(), (float) env.getMaxX(), (float) env[MIN_X], (float) env[MAX_X], (float) env[MIN_Y], (float) env[MAX_Y]);
(float) env.getMinY(), (float) env.getMaxY());
} }
@Override @Override
......
...@@ -5,6 +5,11 @@ ...@@ -5,6 +5,11 @@
*/ */
package org.h2.mvstore.db; package org.h2.mvstore.db;
import static org.h2.util.geometry.GeometryUtils.MAX_X;
import static org.h2.util.geometry.GeometryUtils.MAX_Y;
import static org.h2.util.geometry.GeometryUtils.MIN_X;
import static org.h2.util.geometry.GeometryUtils.MIN_Y;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
...@@ -29,12 +34,11 @@ import org.h2.result.SearchRow; ...@@ -29,12 +34,11 @@ import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.geometry.GeometryUtils;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueGeometry; import org.h2.value.ValueGeometry;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.GeometryFactory;
/** /**
* This is an index based on a MVRTreeMap. * This is an index based on a MVRTreeMap.
...@@ -264,8 +268,7 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex { ...@@ -264,8 +268,7 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
bmaxyf = maxyf; bmaxyf = maxyf;
} }
} }
return ValueGeometry.getFromGeometry(new GeometryFactory().toGeometry( return ValueGeometry.get(GeometryUtils.envelope2wkb(new double[] {bminxf, bmaxxf, bminyf, bmaxyf}));
new Envelope(bminxf, bmaxxf, bminyf, bmaxyf)));
} }
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
} }
...@@ -275,10 +278,10 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex { ...@@ -275,10 +278,10 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
if (v == ValueNull.INSTANCE) { if (v == ValueNull.INSTANCE) {
return new SpatialKey(row.getKey()); return new SpatialKey(row.getKey());
} }
Envelope env = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getEnvelopeNoCopy(); double[] env = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getEnvelopeNoCopy();
return new SpatialKey(row.getKey(), return new SpatialKey(row.getKey(),
(float) env.getMinX(), (float) env.getMaxX(), (float) env[MIN_X], (float) env[MAX_X],
(float) env.getMinY(), (float) env.getMaxY()); (float) env[MIN_Y], (float) env[MAX_Y]);
} }
@Override @Override
...@@ -467,10 +470,9 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex { ...@@ -467,10 +470,9 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
if (hasBounds) { if (hasBounds) {
if ((minxf <= bminxf || maxxf >= bmaxxf || minyf <= bminyf || maxyf >= bmaxyf) if ((minxf <= bminxf || maxxf >= bmaxxf || minyf <= bminyf || maxyf >= bmaxyf)
&& map.containsKey(key)) { && map.containsKey(key)) {
Envelope env = ((ValueGeometry) mvTable.getRow(session, key.getId()).getValue(columnId)) double[] env = ((ValueGeometry) mvTable.getRow(session, key.getId()).getValue(columnId))
.getEnvelopeNoCopy(); .getEnvelopeNoCopy();
double minxd = env.getMinX(), maxxd = env.getMaxX(), minyd = env.getMinY(), double minxd = env[MIN_X], maxxd = env[MAX_X], minyd = env[MIN_Y], maxyd = env[MAX_Y];
maxyd = env.getMaxY();
if (minxd < bminxd) { if (minxd < bminxd) {
bminxf = minxf; bminxf = minxf;
bminxd = minxd; bminxd = minxd;
...@@ -490,16 +492,16 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex { ...@@ -490,16 +492,16 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
} }
} else if (map.containsKey(key)) { } else if (map.containsKey(key)) {
hasBounds = true; hasBounds = true;
Envelope env = ((ValueGeometry) mvTable.getRow(session, key.getId()).getValue(columnId)) double[] env = ((ValueGeometry) mvTable.getRow(session, key.getId()).getValue(columnId))
.getEnvelopeNoCopy(); .getEnvelopeNoCopy();
bminxf = minxf; bminxf = minxf;
bminxd = env.getMinX(); bminxd = env[MIN_X];
bmaxxf = maxxf; bmaxxf = maxxf;
bmaxxd = env.getMaxX(); bmaxxd = env[MAX_X];
bminyf = minyf; bminyf = minyf;
bminyd = env.getMinY(); bminyd = env[MIN_Y];
bmaxyf = maxyf; bmaxyf = maxyf;
bmaxyd = env.getMaxY(); bmaxyd = env[MAX_Y];
} }
} else if (hasBounds) { } else if (hasBounds) {
if (minxf <= bminxf || maxxf >= bmaxxf || minyf <= bminyf || maxyf >= bmaxyf) { if (minxf <= bminxf || maxxf >= bmaxxf || minyf <= bminyf || maxyf >= bmaxyf) {
...@@ -512,8 +514,9 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex { ...@@ -512,8 +514,9 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
} }
Value getBounds() { Value getBounds() {
return hasBounds ? ValueGeometry.getFromGeometry(new GeometryFactory().toGeometry( return hasBounds ? ValueGeometry.get(
new Envelope(bminxd, bmaxxd, bminyd, bmaxyd))) : ValueNull.INSTANCE; GeometryUtils.envelope2wkb(new double[] {bminxd, bmaxxd, bminyd, bmaxyd}))
: ValueNull.INSTANCE;
} }
} }
......
...@@ -550,22 +550,26 @@ public final class GeometryUtils { ...@@ -550,22 +550,26 @@ public final class GeometryUtils {
} else if (envelope2 == null) { } else if (envelope2 == null) {
return envelope1; return envelope1;
} }
double minX1 = envelope1[MIN_X], maxX1 = envelope1[MAX_X], minY1 = envelope1[MIN_Y], maxY1 = envelope1[MAX_Y]; double minX1 = envelope1[MIN_X], maxX1 = envelope1[MAX_X], minY1 = envelope1[MIN_Y], maxY1 = envelope1[MAX_Y];
double minX2 = envelope2[MIN_X], maxX2 = envelope2[MAX_X], minY2 = envelope2[MIN_Y], maxY2 = envelope2[MAX_Y]; double minX2 = envelope2[MIN_X], maxX2 = envelope2[MAX_X], minY2 = envelope2[MIN_Y], maxY2 = envelope2[MAX_Y];
boolean modified = false;
if (minX1 > minX2) { if (minX1 > minX2) {
minX1 = minX2; minX1 = minX2;
modified = true;
} }
if (maxX1 < maxX2) { if (maxX1 < maxX2) {
maxX1 = maxX2; maxX1 = maxX2;
modified = true;
} }
if (minY1 > minY2) { if (minY1 > minY2) {
minY1 = minY2; minY1 = minY2;
modified = true;
} }
if (maxY1 < maxY2) { if (maxY1 < maxY2) {
maxY1 = maxY2; maxY1 = maxY2;
modified = true;
} }
return new double[] { minX1, maxX1, minY1, maxY1 }; return modified ? new double[] { minX1, maxX1, minY1, maxY1 } : envelope1;
} }
/** /**
......
...@@ -898,7 +898,7 @@ public class DataType { ...@@ -898,7 +898,7 @@ public class DataType {
case Value.RESULT_SET: case Value.RESULT_SET:
return ResultSet.class.getName(); return ResultSet.class.getName();
case Value.GEOMETRY: case Value.GEOMETRY:
return GEOMETRY_CLASS_NAME; return GEOMETRY_CLASS != null ? GEOMETRY_CLASS_NAME : String.class.getName();
case Value.INTERVAL_YEAR: case Value.INTERVAL_YEAR:
case Value.INTERVAL_MONTH: case Value.INTERVAL_MONTH:
case Value.INTERVAL_DAY: case Value.INTERVAL_DAY:
......
...@@ -13,17 +13,10 @@ import org.h2.message.DbException; ...@@ -13,17 +13,10 @@ import org.h2.message.DbException;
import org.h2.util.Bits; import org.h2.util.Bits;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.locationtech.jts.geom.CoordinateSequence; import org.h2.util.geometry.EWKTUtils;
import org.locationtech.jts.geom.CoordinateSequenceFilter; import org.h2.util.geometry.GeometryUtils;
import org.locationtech.jts.geom.Envelope; import org.h2.util.geometry.JTSUtils;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
/** /**
* Implementation of the GEOMETRY data type. * Implementation of the GEOMETRY data type.
...@@ -50,22 +43,20 @@ public class ValueGeometry extends Value { ...@@ -50,22 +43,20 @@ public class ValueGeometry extends Value {
* The value. Converted from WKB only on request as conversion from/to WKB * The value. Converted from WKB only on request as conversion from/to WKB
* cost a significant amount of CPU cycles. * cost a significant amount of CPU cycles.
*/ */
private Geometry geometry; private Object geometry;
/** /**
* The envelope of the value. Calculated only on request. * The envelope of the value. Calculated only on request.
*/ */
private Envelope envelope; private double[] envelope;
/** /**
* Create a new geometry objects. * Create a new geometry objects.
* *
* @param bytes the bytes (always known) * @param bytes the EWKB bytes
* @param geometry the geometry object (may be null)
*/ */
private ValueGeometry(byte[] bytes, Geometry geometry) { private ValueGeometry(byte[] bytes) {
this.bytes = bytes; this.bytes = bytes;
this.geometry = geometry;
this.hashCode = Arrays.hashCode(bytes); this.hashCode = Arrays.hashCode(bytes);
} }
...@@ -77,29 +68,7 @@ public class ValueGeometry extends Value { ...@@ -77,29 +68,7 @@ public class ValueGeometry extends Value {
* @return the value * @return the value
*/ */
public static ValueGeometry getFromGeometry(Object o) { public static ValueGeometry getFromGeometry(Object o) {
/* return get(JTSUtils.geometry2ewkb((Geometry) o));
* Do not pass untrusted source geometry object to a cache, use only its WKB
* representation. Geometries are not fully immutable.
*/
return get(convertToWKB((Geometry) o));
}
private static ValueGeometry get(Geometry g) {
byte[] bytes = convertToWKB(g);
return (ValueGeometry) Value.cache(new ValueGeometry(bytes, g));
}
private static byte[] convertToWKB(Geometry g) {
boolean includeSRID = g.getSRID() != 0;
int dimensionCount = getDimensionCount(g);
WKBWriter writer = new WKBWriter(dimensionCount, includeSRID);
return writer.write(g);
}
private static int getDimensionCount(Geometry geometry) {
ZVisitor finder = new ZVisitor();
geometry.apply(finder);
return finder.isFoundZ() ? 3 : 2;
} }
/** /**
...@@ -110,20 +79,8 @@ public class ValueGeometry extends Value { ...@@ -110,20 +79,8 @@ public class ValueGeometry extends Value {
*/ */
public static ValueGeometry get(String s) { public static ValueGeometry get(String s) {
try { try {
int srid; return get(EWKTUtils.ewkt2ewkb(s));
if (s.startsWith("SRID=")) { } catch (RuntimeException ex) {
int idx = s.indexOf(';', 5);
srid = Integer.parseInt(s.substring(5, idx));
s = s.substring(idx + 1);
} else {
srid = 0;
}
/*
* No-arg WKTReader() constructor instantiates a new GeometryFactory and a new
* PrecisionModel anyway, so special case for srid == 0 is not needed.
*/
return get(new WKTReader(new GeometryFactory(new PrecisionModel(), srid)).read(s));
} catch (ParseException | StringIndexOutOfBoundsException | NumberFormatException ex) {
throw DbException.convert(ex); throw DbException.convert(ex);
} }
} }
...@@ -137,11 +94,7 @@ public class ValueGeometry extends Value { ...@@ -137,11 +94,7 @@ public class ValueGeometry extends Value {
*/ */
public static ValueGeometry get(String s, int srid) { public static ValueGeometry get(String s, int srid) {
// This method is not used in H2, but preserved for H2GIS // This method is not used in H2, but preserved for H2GIS
try { return get(srid == 0 ? s : "SRID=" + srid + ';' + s);
return get(new WKTReader(new GeometryFactory(new PrecisionModel(), srid)).read(s));
} catch (ParseException ex) {
throw DbException.convert(ex);
}
} }
/** /**
...@@ -151,7 +104,7 @@ public class ValueGeometry extends Value { ...@@ -151,7 +104,7 @@ 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(bytes, null)); return (ValueGeometry) Value.cache(new ValueGeometry(bytes));
} }
/** /**
...@@ -160,25 +113,15 @@ public class ValueGeometry extends Value { ...@@ -160,25 +113,15 @@ public class ValueGeometry extends Value {
* *
* @return a copy of the geometry object * @return a copy of the geometry object
*/ */
public Geometry getGeometry() { public Object getGeometry() {
Geometry geometry = getGeometryNoCopy();
Geometry copy = geometry.copy();
return copy;
}
public Geometry getGeometryNoCopy() {
if (geometry == null) { if (geometry == null) {
try { try {
/* geometry = JTSUtils.ewkb2geometry(bytes);
* No-arg WKBReader() constructor instantiates a new GeometryFactory and a new } catch (RuntimeException ex) {
* PrecisionModel anyway, so special case for srid == 0 is not needed.
*/
geometry = new WKBReader(new GeometryFactory(new PrecisionModel(), getSRID())).read(bytes);
} catch (ParseException ex) {
throw DbException.convert(ex); throw DbException.convert(ex);
} }
} }
return geometry; return ((Geometry) geometry).copy();
} }
/** /**
...@@ -215,9 +158,9 @@ public class ValueGeometry extends Value { ...@@ -215,9 +158,9 @@ public class ValueGeometry extends Value {
* *
* @return envelope of this geometry * @return envelope of this geometry
*/ */
public Envelope getEnvelopeNoCopy() { public double[] getEnvelopeNoCopy() {
if (envelope == null) { if (envelope == null) {
envelope = getGeometryNoCopy().getEnvelopeInternal(); envelope = GeometryUtils.getEnvelope(bytes);
} }
return envelope; return envelope;
} }
...@@ -230,7 +173,7 @@ public class ValueGeometry extends Value { ...@@ -230,7 +173,7 @@ public class ValueGeometry extends Value {
* @return true if the two overlap * @return true if the two overlap
*/ */
public boolean intersectsBoundingBox(ValueGeometry r) { public boolean intersectsBoundingBox(ValueGeometry r) {
return getEnvelopeNoCopy().intersects(r.getEnvelopeNoCopy()); return GeometryUtils.intersects(getEnvelopeNoCopy(), r.getEnvelopeNoCopy());
} }
/** /**
...@@ -240,10 +183,7 @@ public class ValueGeometry extends Value { ...@@ -240,10 +183,7 @@ public class ValueGeometry extends Value {
* @return the union of this geometry envelope and another geometry envelope * @return the union of this geometry envelope and another geometry envelope
*/ */
public Value getEnvelopeUnion(ValueGeometry r) { public Value getEnvelopeUnion(ValueGeometry r) {
GeometryFactory gf = new GeometryFactory(); return get(GeometryUtils.envelope2wkb(GeometryUtils.union(getEnvelopeNoCopy(), r.getEnvelopeNoCopy())));
Envelope mergedEnvelope = new Envelope(getEnvelopeNoCopy());
mergedEnvelope.expandToInclude(r.getEnvelopeNoCopy());
return get(gf.toGeometry(mergedEnvelope));
} }
@Override @Override
...@@ -253,13 +193,13 @@ public class ValueGeometry extends Value { ...@@ -253,13 +193,13 @@ public class ValueGeometry extends Value {
@Override @Override
public String getSQL() { public String getSQL() {
// Using bytes is faster than converting EWKB to Geometry then EWKT. // Using bytes is faster than converting to EWKT.
return "X'" + StringUtils.convertBytesToHex(getBytesNoCopy()) + "'::Geometry"; return "X'" + StringUtils.convertBytesToHex(getBytesNoCopy()) + "'::Geometry";
} }
@Override @Override
public int compareTypeSafe(Value v, CompareMode mode) { public int compareTypeSafe(Value v, CompareMode mode) {
return getGeometryNoCopy().compareTo(((ValueGeometry) v).getGeometryNoCopy()); return Bits.compareNotNullUnsigned(bytes, ((ValueGeometry) v).bytes);
} }
@Override @Override
...@@ -279,23 +219,25 @@ public class ValueGeometry extends Value { ...@@ -279,23 +219,25 @@ public class ValueGeometry extends Value {
@Override @Override
public Object getObject() { public Object getObject() {
return getGeometry(); if (DataType.GEOMETRY_CLASS != null) {
return getGeometry();
}
return getEWKT();
} }
@Override @Override
public byte[] getBytes() { public byte[] getBytes() {
return Utils.cloneByteArray(getEWKB()); return Utils.cloneByteArray(bytes);
} }
@Override @Override
public byte[] getBytesNoCopy() { public byte[] getBytesNoCopy() {
return getEWKB(); return bytes;
} }
@Override @Override
public void set(PreparedStatement prep, int parameterIndex) public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
throws SQLException { prep.setBytes(parameterIndex, bytes);
prep.setObject(parameterIndex, getGeometryNoCopy());
} }
@Override @Override
...@@ -310,10 +252,7 @@ public class ValueGeometry extends Value { ...@@ -310,10 +252,7 @@ public class ValueGeometry extends Value {
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
// The JTS library only does half-way support for 3D coordinates, so return other instanceof ValueGeometry && Arrays.equals(getEWKB(), ((ValueGeometry) other).getEWKB());
// their equals method only checks the first two coordinates.
return other instanceof ValueGeometry &&
Arrays.equals(getEWKB(), ((ValueGeometry) other).getEWKB());
} }
/** /**
...@@ -322,12 +261,7 @@ public class ValueGeometry extends Value { ...@@ -322,12 +261,7 @@ public class ValueGeometry extends Value {
* @return the extended well-known text * @return the extended well-known text
*/ */
public String getEWKT() { public String getEWKT() {
String wkt = new WKTWriter(3).write(getGeometryNoCopy()); return EWKTUtils.ewkb2ewkt(bytes);
int srid = getSRID();
return srid == 0
? wkt
// "SRID=-2147483648;".length() == 17
: new StringBuilder(wkt.length() + 17).append("SRID=").append(srid).append(';').append(wkt).toString();
} }
/** /**
...@@ -347,40 +281,4 @@ public class ValueGeometry extends Value { ...@@ -347,40 +281,4 @@ public class ValueGeometry extends Value {
return super.convertTo(targetType, precision, mode, column, null); return super.convertTo(targetType, precision, mode, column, null);
} }
/**
* A visitor that checks if there is a Z coordinate.
*/
static class ZVisitor implements CoordinateSequenceFilter {
private boolean foundZ;
public boolean isFoundZ() {
return foundZ;
}
/**
* Performs an operation on a coordinate in a CoordinateSequence.
*
* @param coordinateSequence the object to which the filter is applied
* @param i the index of the coordinate to apply the filter to
*/
@Override
public void filter(CoordinateSequence coordinateSequence, int i) {
if (!Double.isNaN(coordinateSequence.getOrdinate(i, 2))) {
foundZ = true;
}
}
@Override
public boolean isDone() {
return foundZ;
}
@Override
public boolean isGeometryChanged() {
return false;
}
}
} }
...@@ -612,12 +612,13 @@ public class TestSpatial extends TestDb { ...@@ -612,12 +612,13 @@ public class TestSpatial extends TestDb {
ValueGeometry geom3d = ValueGeometry.get(ewkt); ValueGeometry geom3d = ValueGeometry.get(ewkt);
assertEquals(ewkt, geom3d.getString()); assertEquals(ewkt, geom3d.getString());
ValueGeometry copy = ValueGeometry.get(geom3d.getBytes()); ValueGeometry copy = ValueGeometry.get(geom3d.getBytes());
assertEquals(6, copy.getGeometry().getCoordinates()[0].z); Geometry g = (Geometry) copy.getGeometry();
assertEquals(5, copy.getGeometry().getCoordinates()[1].z); assertEquals(6, g.getCoordinates()[0].z);
assertEquals(4, copy.getGeometry().getCoordinates()[2].z); assertEquals(5, g.getCoordinates()[1].z);
assertEquals(4, g.getCoordinates()[2].z);
// Test SRID // Test SRID
copy = ValueGeometry.get(geom3d.getBytes()); copy = ValueGeometry.get(geom3d.getBytes());
assertEquals(27572, copy.getGeometry().getSRID()); assertEquals(27572, g.getSRID());
Point point = new GeometryFactory().createPoint((new Coordinate(1.1d, 1.2d))); Point point = new GeometryFactory().createPoint((new Coordinate(1.1d, 1.2d)));
// SRID 0 // SRID 0
...@@ -696,7 +697,7 @@ public class TestSpatial extends TestDb { ...@@ -696,7 +697,7 @@ public class TestSpatial extends TestDb {
assertFalse(valueGeometry.equals(valueGeometry2)); assertFalse(valueGeometry.equals(valueGeometry2));
ValueGeometry valueGeometry3 = ValueGeometry.getFromGeometry(geometry); ValueGeometry valueGeometry3 = ValueGeometry.getFromGeometry(geometry);
assertEquals(valueGeometry, valueGeometry3); assertEquals(valueGeometry, valueGeometry3);
assertEquals(geometry.getSRID(), valueGeometry3.getGeometry().getSRID()); assertEquals(geometry.getSRID(), ((Geometry) valueGeometry3.getGeometry()).getSRID());
// Check illegal geometry (no WKB representation) // Check illegal geometry (no WKB representation)
try { try {
ValueGeometry.get("POINT EMPTY"); ValueGeometry.get("POINT EMPTY");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论