Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
df4cc289
提交
df4cc289
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add extended parameters for GEOMETRY data type
上级
e5098b56
master
version-1.4.198
无相关合并请求
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
370 行增加
和
56 行删除
+370
-56
Parser.java
h2/src/main/org/h2/command/Parser.java
+27
-0
CreateTable.java
h2/src/main/org/h2/command/ddl/CreateTable.java
+8
-6
Column.java
h2/src/main/org/h2/table/Column.java
+6
-1
TableView.java
h2/src/main/org/h2/table/TableView.java
+2
-1
EWKBUtils.java
h2/src/main/org/h2/util/geometry/EWKBUtils.java
+29
-3
EWKTUtils.java
h2/src/main/org/h2/util/geometry/EWKTUtils.java
+99
-6
GeometryUtils.java
h2/src/main/org/h2/util/geometry/GeometryUtils.java
+7
-7
DataType.java
h2/src/main/org/h2/value/DataType.java
+22
-1
ExtTypeInfoGeometry.java
h2/src/main/org/h2/value/ExtTypeInfoGeometry.java
+68
-0
ValueGeometry.java
h2/src/main/org/h2/value/ValueGeometry.java
+63
-29
TestGeometryUtils.java
h2/src/test/org/h2/test/unit/TestGeometryUtils.java
+39
-2
没有找到文件。
h2/src/main/org/h2/command/Parser.java
浏览文件 @
df4cc289
...
...
@@ -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.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/ddl/CreateTable.java
浏览文件 @
df4cc289
...
...
@@ -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
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/Column.java
浏览文件 @
df4cc289
...
...
@@ -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
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/TableView.java
浏览文件 @
df4cc289
...
...
@@ -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
();
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/geometry/EWKBUtils.java
浏览文件 @
df4cc289
...
...
@@ -233,17 +233,17 @@ public final class EWKBUtils {
/**
* Geometry type mask that indicates presence of dimension Z.
*/
p
rivate
static
final
int
EWKB_Z
=
0x8000_0000
;
p
ublic
static
final
int
EWKB_Z
=
0x8000_0000
;
/**
* Geometry type mask that indicates presence of dimension M.
*/
p
rivate
static
final
int
EWKB_M
=
0x4000_0000
;
p
ublic
static
final
int
EWKB_M
=
0x4000_0000
;
/**
* Geometry type mask that indicates presence of SRID.
*/
p
rivate
static
final
int
EWKB_SRID
=
0x2000_0000
;
p
ublic
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.
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/geometry/EWKTUtils.java
浏览文件 @
df4cc289
...
...
@@ -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.
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/geometry/GeometryUtils.java
浏览文件 @
df4cc289
...
...
@@ -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.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/DataType.java
浏览文件 @
df4cc289
...
...
@@ -358,7 +358,7 @@ public class DataType {
104
);
add
(
Value
.
GEOMETRY
,
Types
.
OTHER
,
create
String
(
false
),
create
Geometry
(
),
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.
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ExtTypeInfoGeometry.java
0 → 100644
浏览文件 @
df4cc289
/*
* 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
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueGeometry.java
浏览文件 @
df4cc289
...
...
@@ -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
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestGeometryUtils.java
浏览文件 @
df4cc289
...
...
@@ -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 "
)));
}
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论