提交 df4cc289 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add extended parameters for GEOMETRY data type

上级 e5098b56
......@@ -194,10 +194,12 @@ import org.h2.util.ParserUtil;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
import org.h2.util.geometry.EWKTUtils;
import org.h2.value.CompareMode;
import org.h2.value.DataType;
import org.h2.value.ExtTypeInfo;
import org.h2.value.ExtTypeInfoEnum;
import org.h2.value.ExtTypeInfoGeometry;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueBytes;
......@@ -5027,6 +5029,31 @@ public class Parser {
}
original += extTypeInfo.toString();
}
} else if (dataType.type == Value.GEOMETRY) {
if (extTypeInfo == null) {
if (readIf(OPEN_PAREN)) {
int type = 0;
if (currentTokenType == IDENTIFIER && !currentTokenQuoted) {
try {
type = EWKTUtils.parseGeometryType(currentToken);
read();
if (type / 1_000 == 0 && currentTokenType == IDENTIFIER && !currentTokenQuoted) {
type += EWKTUtils.parseDimensionSystem(currentToken) * 1_000;
read();
}
} catch (IllegalArgumentException ex) {
throw getSyntaxError();
}
}
Integer srid = null;
if (type == 0 || readIf(COMMA)) {
srid = readInt();
}
read(CLOSE_PAREN);
extTypeInfo = new ExtTypeInfoGeometry(type, srid);
original += extTypeInfo.toString();
}
}
} else if (readIf(OPEN_PAREN)) {
// Support for MySQL: INT(11), MEDIUMINT(8) and so on.
// Just ignore the precision.
......
......@@ -199,15 +199,17 @@ public class CreateTable extends CommandWithColumns {
precision = scale;
}
ExtTypeInfo extTypeInfo = null;
if (dt.type == Value.ENUM) {
/**
* Only columns of tables may be enumerated.
*/
if (!(expr instanceof ExpressionColumn)) {
int t = dt.type;
if (DataType.isExtInfoType(t)) {
if (expr instanceof ExpressionColumn) {
extTypeInfo = ((ExpressionColumn) expr).getColumn().getExtTypeInfo();
} else if (t == Value.ENUM) {
/*
* Only columns of tables may be enumerated.
*/
throw DbException.get(ErrorCode.GENERAL_ERROR_1,
"Unable to resolve enumerators of expression");
}
extTypeInfo = ((ExpressionColumn) expr).getColumn().getExtTypeInfo();
}
Column col = new Column(name, type, precision, scale, displaySize, extTypeInfo);
addColumn(col);
......
......@@ -402,7 +402,7 @@ public class Column {
getCreateSQL(), s + " (" + value.getPrecision() + ")");
}
}
if (type == Value.ENUM && value != ValueNull.INSTANCE) {
if (value != ValueNull.INSTANCE && DataType.isExtInfoType(type) && extTypeInfo != null) {
value = extTypeInfo.cast(value);
}
updateSequenceIfRequired(session, value);
......@@ -509,6 +509,11 @@ public class Column {
case Value.DECIMAL:
buff.append('(').append(precision).append(", ").append(scale).append(')');
break;
case Value.GEOMETRY:
if (extTypeInfo == null) {
break;
}
//$FALL-THROUGH$
case Value.ENUM:
buff.append(extTypeInfo.toString());
break;
......
......@@ -38,6 +38,7 @@ import org.h2.util.ColumnNamer;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
import org.h2.value.DataType;
import org.h2.value.ExtTypeInfo;
import org.h2.value.Value;
......@@ -196,7 +197,7 @@ public class TableView extends Table {
int scale = expr.getScale();
int displaySize = expr.getDisplaySize();
ExtTypeInfo extTypeInfo = null;
if (type == Value.ENUM) {
if (DataType.isExtInfoType(type)) {
if (expr instanceof ExpressionColumn) {
extTypeInfo = ((ExpressionColumn) expr).getColumn().getExtTypeInfo();
}
......
......@@ -233,17 +233,17 @@ public final class EWKBUtils {
/**
* Geometry type mask that indicates presence of dimension Z.
*/
private static final int EWKB_Z = 0x8000_0000;
public static final int EWKB_Z = 0x8000_0000;
/**
* Geometry type mask that indicates presence of dimension M.
*/
private static final int EWKB_M = 0x4000_0000;
public static final int EWKB_M = 0x4000_0000;
/**
* Geometry type mask that indicates presence of SRID.
*/
private static final int EWKB_SRID = 0x2000_0000;
public static final int EWKB_SRID = 0x2000_0000;
/**
* Converts any supported EWKB to EWKB representation that is used by this
......@@ -296,6 +296,32 @@ public final class EWKBUtils {
}
}
/**
* Converts geometry type with flags to a dimension system.
*
* @param type
* geometry type with flags
* @return dimension system
*/
public static int type2dimensionSystem(int type) {
// PostGIS extensions
boolean useZ = (type & EWKB_Z) != 0;
boolean useM = (type & EWKB_M) != 0;
// OGC 06-103r4
type &= 0xffff;
switch (type / 1_000) {
case DIMENSION_SYSTEM_XYZ:
useZ = true;
break;
case DIMENSION_SYSTEM_XYZM:
useZ = true;
//$FALL-THROUGH$
case DIMENSION_SYSTEM_XYM:
useM = true;
}
return (useZ ? DIMENSION_SYSTEM_XYZ : 0) | (useM ? DIMENSION_SYSTEM_XYM : 0);
}
/**
* Parses a EWKB.
*
......
......@@ -41,6 +41,30 @@ import org.h2.util.geometry.GeometryUtils.Target;
*/
public final class EWKTUtils {
/**
* 0-based type names of geometries, subtract 1 from type code to get index
* in this array.
*/
private static final String[] TYPES = { //
"POINT", //
"LINESTRING", //
"POLYGON", //
"MULTIPOINT", //
"MULTILINESTRING", //
"MULTIPOLYGON", //
"GEOMETRYCOLLECTION", //
};
/**
* Names of dimension systems.
*/
private static final String[] DIMENSION_SYTEMS = { //
"XY", //
"Z", //
"M", //
"ZM", //
};
/**
* Converter output target that writes a EWKT.
*/
......@@ -328,7 +352,7 @@ public final class EWKTUtils {
int o = offset;
skipWS();
int len = ewkt.length();
if (offset > len - 2) {
if (offset >= len) {
throw new IllegalArgumentException();
}
int result;
......@@ -342,12 +366,16 @@ public final class EWKTUtils {
case 'Z':
case 'z':
offset++;
ch = ewkt.charAt(offset);
if (ch == 'M' || ch == 'm') {
offset++;
result = DIMENSION_SYSTEM_XYZM;
} else {
if (offset >= len) {
result = DIMENSION_SYSTEM_XYZ;
} else {
ch = ewkt.charAt(offset);
if (ch == 'M' || ch == 'm') {
offset++;
result = DIMENSION_SYSTEM_XYZM;
} else {
result = DIMENSION_SYSTEM_XYZ;
}
}
break;
default:
......@@ -589,6 +617,71 @@ public final class EWKTUtils {
parseEWKT(new EWKTSource(ewkt), target, 0, 0);
}
/**
* Parses geometry type and dimension system from the given string.
*
* @param s
* string to parse
* @return geometry type and dimension system in OGC geometry code format
* (type + dimensionSystem * 1000)
* @throws IllegalArgumentException
* if input is not valid
*/
public static int parseGeometryType(String s) {
EWKTSource source = new EWKTSource(s);
int type = source.readType();
int dimensionSystem = 0;
if (source.hasData()) {
dimensionSystem = source.readDimensionSystem();
if (source.hasData()) {
throw new IllegalArgumentException();
}
}
return dimensionSystem * 1_000 + type;
}
/**
* Parses a dimension system from the given string.
*
* @param s
* string to parse
* @return dimension system, one of XYZ, XYM, or XYZM
* @see GeometryUtils#DIMENSION_SYSTEM_XYZ
* @see GeometryUtils#DIMENSION_SYSTEM_XYM
* @see GeometryUtils#DIMENSION_SYSTEM_XYZM
* @throws IllegalArgumentException
* if input is not valid
*/
public static int parseDimensionSystem(String s) {
EWKTSource source = new EWKTSource(s);
int dimensionSystem = source.readDimensionSystem();
if (source.hasData() || dimensionSystem == DIMENSION_SYSTEM_XY) {
throw new IllegalArgumentException();
}
return dimensionSystem;
}
/**
* Formats type and dimension system as a string.
*
* @param type
* OGC geometry code format (type + dimensionSystem * 1000)
* @return formatted string
* @throws IllegalArgumentException
* if type is not valid
*/
public static String formatGeometryTypeAndDimensionSystem(int type) {
int t = type % 1_000, d = type / 1_000;
if (t < POINT || t > GEOMETRY_COLLECTION || d < DIMENSION_SYSTEM_XY || d > DIMENSION_SYSTEM_XYZM) {
throw new IllegalArgumentException();
}
String result = TYPES[t - 1];
if (d != DIMENSION_SYSTEM_XY) {
result = result + ' ' + DIMENSION_SYTEMS[d];
}
return result;
}
/**
* Parses a EWKB.
*
......
......@@ -362,37 +362,37 @@ public final class GeometryUtils {
/**
* POINT geometry type.
*/
static final int POINT = 1;
public static final int POINT = 1;
/**
* LINESTRING geometry type.
*/
static final int LINE_STRING = 2;
public static final int LINE_STRING = 2;
/**
* POLYGON geometry type.
*/
static final int POLYGON = 3;
public static final int POLYGON = 3;
/**
* MULTIPOINT geometry type.
*/
static final int MULTI_POINT = 4;
public static final int MULTI_POINT = 4;
/**
* MULTILINESTRING geometry type.
*/
static final int MULTI_LINE_STRING = 5;
public static final int MULTI_LINE_STRING = 5;
/**
* MULTIPOLYGON geometry type.
*/
static final int MULTI_POLYGON = 6;
public static final int MULTI_POLYGON = 6;
/**
* GEOMETRYCOLLECTION geometry type.
*/
static final int GEOMETRY_COLLECTION = 7;
public static final int GEOMETRY_COLLECTION = 7;
/**
* Number of X coordinate.
......
......@@ -358,7 +358,7 @@ public class DataType {
104
);
add(Value.GEOMETRY, Types.OTHER,
createString(false),
createGeometry(),
new String[]{"GEOMETRY"},
32
);
......@@ -548,6 +548,17 @@ public class DataType {
return t;
}
private static DataType createGeometry() {
DataType dataType = new DataType();
dataType.prefix = "'";
dataType.suffix = "'";
dataType.params = "TYPE,SRID";
dataType.maxPrecision = Integer.MAX_VALUE;
dataType.defaultPrecision = Integer.MAX_VALUE;
dataType.defaultDisplaySize = Integer.MAX_VALUE;
return dataType;
}
/**
* Get the list of data types.
*
......@@ -1403,6 +1414,16 @@ public class DataType {
return type == Value.STRING || type == Value.STRING_FIXED || type == Value.STRING_IGNORECASE;
}
/**
* Check if the given type may have extended type information.
*
* @param type the value type
* @return true if the value type may have extended type information
*/
public static boolean isExtInfoType(int type) {
return type == Value.GEOMETRY || type == Value.ENUM;
}
/**
* Check if the given value type supports the add operation.
*
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.value;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.geometry.EWKTUtils;
/**
* Extended parameters of the GEOMETRY data type.
*/
public final class ExtTypeInfoGeometry extends ExtTypeInfo {
private final int type;
private final Integer srid;
private static String toString(int type, Integer srid) {
if (type == 0 && srid == null) {
return "";
}
StringBuilder builder = new StringBuilder();
builder.append('(');
if (type != 0) {
builder.append(EWKTUtils.formatGeometryTypeAndDimensionSystem(type));
}
if (srid != null) {
if (type != 0) {
builder.append(", ");
}
builder.append((int) srid);
}
return builder.append(')').toString();
}
/**
* Creates new instance of extended parameters of the GEOMETRY data type.
*
* @param type
* the type and dimension system of geometries, or 0 if not
* constrained
* @param srid
* the SRID of geometries, or {@code null} if not constrained
*/
public ExtTypeInfoGeometry(int type, Integer srid) {
this.type = type;
this.srid = srid;
}
@Override
public Value cast(Value value) {
ValueGeometry g = (ValueGeometry) value.convertTo(Value.GEOMETRY);
if (type != 0 && g.getTypeAndDimensionSystem() != type || srid != null && g.getSRID() != srid) {
throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1,
toString(g.getTypeAndDimensionSystem(), g.getSRID()) + " <> " + toString());
}
return g;
}
@Override
public String toString() {
return toString(type, srid);
}
}
......@@ -5,6 +5,7 @@
*/
package org.h2.value;
import static org.h2.util.geometry.EWKBUtils.EWKB_SRID;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
......@@ -18,6 +19,7 @@ import org.h2.util.geometry.EWKBUtils;
import org.h2.util.geometry.EWKTUtils;
import org.h2.util.geometry.GeometryUtils;
import org.h2.util.geometry.GeometryUtils.EnvelopeAndDimensionSystemTarget;
import org.h2.util.geometry.GeometryUtils.EnvelopeTarget;
import org.h2.util.geometry.JTSUtils;
import org.locationtech.jts.geom.Geometry;
......@@ -30,6 +32,8 @@ import org.locationtech.jts.geom.Geometry;
*/
public class ValueGeometry extends Value {
private static final double[] UNKNOWN_ENVELOPE = new double[0];
/**
* As conversion from/to WKB cost a significant amount of CPU cycles, WKB
* are kept in ValueGeometry instance.
......@@ -43,9 +47,15 @@ public class ValueGeometry extends Value {
private final int hashCode;
/**
* Dimension system. -1 if not known yet.
* Geometry type and dimension system in OGC geometry code format (type +
* dimensionSystem * 1000).
*/
private final int typeAndDimensionSystem;
/**
* Spatial reference system identifier.
*/
private int dimensionSystem;
private final int srid;
/**
* The envelope of the value. Calculated only on request.
......@@ -62,14 +72,18 @@ public class ValueGeometry extends Value {
* Create a new geometry object.
*
* @param bytes the EWKB bytes
* @param dimensionSystem dimension system
* @param envelope the envelope
*/
private ValueGeometry(byte[] bytes, int dimensionSystem, double[] envelope) {
private ValueGeometry(byte[] bytes, double[] envelope) {
if (bytes.length < 9 || bytes[0] != 0) {
throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, StringUtils.convertBytesToHex(bytes));
}
this.bytes = bytes;
this.hashCode = Arrays.hashCode(bytes);
this.dimensionSystem = dimensionSystem;
this.envelope = envelope;
int t = Bits.readInt(bytes, 1);
srid = (t & EWKB_SRID) != 0 ? Bits.readInt(bytes, 5) : 0;
typeAndDimensionSystem = (t & 0xffff) % 1_000 + EWKBUtils.type2dimensionSystem(t) * 1_000;
hashCode = Arrays.hashCode(bytes);
}
/**
......@@ -84,9 +98,8 @@ public class ValueGeometry extends Value {
EnvelopeAndDimensionSystemTarget target = new EnvelopeAndDimensionSystemTarget();
Geometry g = (Geometry) o;
JTSUtils.parseGeometry(g, target);
int dimensionSystem = target.getDimensionSystem();
return (ValueGeometry) Value.cache(new ValueGeometry(JTSUtils.geometry2ewkb(g, dimensionSystem),
dimensionSystem, target.getEnvelope()));
return (ValueGeometry) Value.cache(new ValueGeometry( //
JTSUtils.geometry2ewkb(g, target.getDimensionSystem()), target.getEnvelope()));
} catch (RuntimeException ex) {
throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, String.valueOf(o));
}
......@@ -102,9 +115,8 @@ public class ValueGeometry extends Value {
try {
EnvelopeAndDimensionSystemTarget target = new EnvelopeAndDimensionSystemTarget();
EWKTUtils.parseEWKT(s, target);
int dimensionSystem = target.getDimensionSystem();
return (ValueGeometry) Value.cache(new ValueGeometry(EWKTUtils.ewkt2ewkb(s, dimensionSystem),
dimensionSystem, target.getEnvelope()));
return (ValueGeometry) Value.cache(new ValueGeometry( //
EWKTUtils.ewkt2ewkb(s, target.getDimensionSystem()), target.getEnvelope()));
} catch (RuntimeException ex) {
throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, s);
}
......@@ -129,7 +141,7 @@ public class ValueGeometry extends Value {
* @return the value
*/
public static ValueGeometry get(byte[] bytes) {
return (ValueGeometry) Value.cache(new ValueGeometry(bytes, -1, null));
return (ValueGeometry) Value.cache(new ValueGeometry(bytes, UNKNOWN_ENVELOPE));
}
/**
......@@ -142,9 +154,8 @@ public class ValueGeometry extends Value {
try {
EnvelopeAndDimensionSystemTarget target = new EnvelopeAndDimensionSystemTarget();
EWKBUtils.parseEWKB(bytes, target);
int dimensionSystem = target.getDimensionSystem();
return (ValueGeometry) Value.cache(new ValueGeometry(EWKBUtils.ewkb2ewkb(bytes, dimensionSystem),
dimensionSystem, target.getEnvelope()));
return (ValueGeometry) Value.cache(new ValueGeometry( //
EWKBUtils.ewkb2ewkb(bytes, target.getDimensionSystem()), target.getEnvelope()));
} catch (RuntimeException ex) {
throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, StringUtils.convertBytesToHex(bytes));
}
......@@ -158,8 +169,7 @@ public class ValueGeometry extends Value {
*/
public static Value fromEnvelope(double[] envelope) {
return envelope != null
? Value.cache(new ValueGeometry(EWKBUtils.envelope2wkb(envelope), GeometryUtils.DIMENSION_SYSTEM_XY,
envelope))
? Value.cache(new ValueGeometry(EWKBUtils.envelope2wkb(envelope), envelope))
: ValueNull.INSTANCE;
}
......@@ -180,13 +190,23 @@ public class ValueGeometry extends Value {
return ((Geometry) geometry).copy();
}
private void calculateInfo() {
if (dimensionSystem < 0) {
EnvelopeAndDimensionSystemTarget target = new EnvelopeAndDimensionSystemTarget();
EWKBUtils.parseEWKB(bytes, target);
envelope = target.getEnvelope();
dimensionSystem = target.getDimensionSystem();
}
/**
* Returns geometry type and dimension system in OGC geometry code format
* (type + dimensionSystem * 1000).
*
* @return geometry type and dimension system
*/
public int getTypeAndDimensionSystem() {
return typeAndDimensionSystem;
}
/**
* Returns geometry type.
*
* @return geometry type and dimension system
*/
public int getGeometryType() {
return typeAndDimensionSystem % 1_000;
}
/**
......@@ -195,8 +215,16 @@ public class ValueGeometry extends Value {
* @return dimension system
*/
public int getDimensionSystem() {
calculateInfo();
return dimensionSystem;
return typeAndDimensionSystem / 1_000;
}
/**
* Return a spatial reference system identifier.
*
* @return spatial reference system identifier
*/
public int getSRID() {
return srid;
}
/**
......@@ -205,7 +233,11 @@ public class ValueGeometry extends Value {
* @return envelope of this geometry
*/
public double[] getEnvelopeNoCopy() {
calculateInfo();
if (envelope == UNKNOWN_ENVELOPE) {
EnvelopeTarget target = new EnvelopeTarget();
EWKBUtils.parseEWKB(bytes, target);
envelope = target.getEnvelope();
}
return envelope;
}
......@@ -319,7 +351,9 @@ public class ValueGeometry extends Value {
@Override
public Value convertTo(int targetType, int precision, Mode mode, Object column, ExtTypeInfo extTypeInfo) {
if (targetType == Value.JAVA_OBJECT) {
if (targetType == Value.GEOMETRY) {
return extTypeInfo != null ? extTypeInfo.cast(this) : this;
} else if (targetType == Value.JAVA_OBJECT) {
return this;
}
return super.convertTo(targetType, precision, mode, column, null);
......
......@@ -8,6 +8,8 @@ package org.h2.test.unit;
import static org.h2.util.geometry.GeometryUtils.DIMENSION_SYSTEM_XY;
import static org.h2.util.geometry.GeometryUtils.DIMENSION_SYSTEM_XYM;
import static org.h2.util.geometry.GeometryUtils.DIMENSION_SYSTEM_XYZ;
import static org.h2.util.geometry.GeometryUtils.DIMENSION_SYSTEM_XYZM;
import static org.h2.util.geometry.GeometryUtils.GEOMETRY_COLLECTION;
import static org.h2.util.geometry.GeometryUtils.M;
import static org.h2.util.geometry.GeometryUtils.MAX_X;
import static org.h2.util.geometry.GeometryUtils.MAX_Y;
......@@ -33,6 +35,7 @@ import org.h2.util.geometry.GeometryUtils.EnvelopeAndDimensionSystemTarget;
import org.h2.util.geometry.GeometryUtils.Target;
import org.h2.util.geometry.JTSUtils;
import org.h2.util.geometry.JTSUtils.GeometryTarget;
import org.h2.value.ValueGeometry;
import org.locationtech.jts.geom.CoordinateSequence;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
......@@ -234,8 +237,11 @@ public class TestGeometryUtils extends TestBase {
testEnvelope(envelopeFromJTS, target.getEnvelope());
// Test dimensions
testDimensions(numOfDimensions > 2 ? GeometryUtils.DIMENSION_SYSTEM_XYZ : GeometryUtils.DIMENSION_SYSTEM_XY,
wkbFromJTS);
int expectedDimensionSystem = numOfDimensions > 2 ? GeometryUtils.DIMENSION_SYSTEM_XYZ
: GeometryUtils.DIMENSION_SYSTEM_XY;
testDimensions(expectedDimensionSystem, wkbFromJTS);
testValueGeometryProperties(wkbFromJTS);
}
private void testEnvelope(Envelope envelopeFromJTS, double[] envelopeFromH2) {
......@@ -274,6 +280,7 @@ public class TestGeometryUtils extends TestBase {
testDimensionMCheckPoint(cs);
assertEquals(ewkb, JTSUtils.geometry2ewkb(p));
testDimensions(GeometryUtils.DIMENSION_SYSTEM_XYM, ewkb);
testValueGeometryProperties(ewkb);
if (JTSUtils.M_IS_SUPPORTED) {
p = (Point) new WKTReader().read("POINT M (1 2 3)");
......@@ -310,6 +317,7 @@ public class TestGeometryUtils extends TestBase {
testDimensionZMCheckPoint(cs);
assertEquals(ewkb, JTSUtils.geometry2ewkb(p));
testDimensions(GeometryUtils.DIMENSION_SYSTEM_XYZM, ewkb);
testValueGeometryProperties(ewkb);
if (JTSUtils.M_IS_SUPPORTED) {
p = (Point) new WKTReader().read("POINT ZM (1 2 3 4)");
......@@ -333,6 +341,32 @@ public class TestGeometryUtils extends TestBase {
assertEquals(4, cs.getOrdinate(0, M));
}
private void testValueGeometryProperties(byte[] ewkb) {
ValueGeometry vg = ValueGeometry.getFromEWKB(ewkb);
DimensionSystemTarget target = new DimensionSystemTarget();
EWKBUtils.parseEWKB(ewkb, target);
int dimensionSystem = target.getDimensionSystem();
assertEquals(dimensionSystem, vg.getDimensionSystem());
String formattedType = EWKTUtils.formatGeometryTypeAndDimensionSystem(vg.getTypeAndDimensionSystem());
assertTrue(EWKTUtils.ewkb2ewkt(ewkb).startsWith(formattedType));
switch (dimensionSystem) {
case DIMENSION_SYSTEM_XY:
assertTrue(formattedType.indexOf(' ') < 0);
break;
case DIMENSION_SYSTEM_XYZ:
assertTrue(formattedType.endsWith(" Z"));
break;
case DIMENSION_SYSTEM_XYM:
assertTrue(formattedType.endsWith(" M"));
break;
case DIMENSION_SYSTEM_XYZM:
assertTrue(formattedType.endsWith(" ZM"));
break;
}
assertEquals(vg.getTypeAndDimensionSystem(), vg.getGeometryType() + vg.getDimensionSystem() * 1_000);
assertEquals(0, vg.getSRID());
}
private void testFiniteOnly() {
for (int i = 0; i < NON_FINITE.length; i++) {
testFiniteOnly(NON_FINITE[i], new EWKBTarget(new ByteArrayOutputStream(), NON_FINITE_DIMENSIONS[i]));
......@@ -381,6 +415,9 @@ public class TestGeometryUtils extends TestBase {
assertEquals(10, gc.getSRID());
assertEquals(10, gc.getGeometryN(0).getSRID());
assertEquals(ewkb, JTSUtils.geometry2ewkb(gc));
ValueGeometry vg = ValueGeometry.getFromEWKB(ewkb);
assertEquals(10, vg.getSRID());
assertEquals(GEOMETRY_COLLECTION, vg.getTypeAndDimensionSystem());
assertEquals("SRID=-1;POINT EMPTY", EWKTUtils.ewkb2ewkt(EWKTUtils.ewkt2ewkb(" srid=-1 ; POINT EMPTY ")));
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论