Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
6aa1cc4a
Commit
6aa1cc4a
authored
Mar 12, 2004
by
hf@deer.(none)
Browse files
Options
Browse Files
Download
Plain Diff
Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-4.1
into deer.(none):/home/hf/work/mysql-4.1.spa
parents
0be2ef68
f2366bf0
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
497 additions
and
447 deletions
+497
-447
sql/field.cc
sql/field.cc
+11
-7
sql/item_geofunc.cc
sql/item_geofunc.cc
+141
-112
sql/spatial.cc
sql/spatial.cc
+224
-162
sql/spatial.h
sql/spatial.h
+114
-159
sql/sql_yacc.yy
sql/sql_yacc.yy
+7
-7
No files found.
sql/field.cc
View file @
6aa1cc4a
...
@@ -4765,7 +4765,8 @@ void Field_blob::get_key_image(char *buff,uint length,
...
@@ -4765,7 +4765,8 @@ void Field_blob::get_key_image(char *buff,uint length,
{
{
const
char
*
dummy
;
const
char
*
dummy
;
MBR
mbr
;
MBR
mbr
;
Geometry
gobj
;
Geometry_buffer
buffer
;
Geometry
*
gobj
;
if
(
blob_length
<
SRID_SIZE
)
if
(
blob_length
<
SRID_SIZE
)
{
{
...
@@ -4773,8 +4774,9 @@ void Field_blob::get_key_image(char *buff,uint length,
...
@@ -4773,8 +4774,9 @@ void Field_blob::get_key_image(char *buff,uint length,
return
;
return
;
}
}
get_ptr
(
&
blob
);
get_ptr
(
&
blob
);
gobj
.
create_from_wkb
(
blob
+
SRID_SIZE
,
blob_length
-
SRID_SIZE
);
gobj
=
Geometry
::
create_from_wkb
(
&
buffer
,
if
(
gobj
.
get_mbr
(
&
mbr
,
&
dummy
))
blob
+
SRID_SIZE
,
blob_length
-
SRID_SIZE
);
if
(
gobj
->
get_mbr
(
&
mbr
,
&
dummy
))
bzero
(
buff
,
SIZEOF_STORED_DOUBLE
*
4
);
bzero
(
buff
,
SIZEOF_STORED_DOUBLE
*
4
);
else
else
{
{
...
@@ -5013,9 +5015,11 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
...
@@ -5013,9 +5015,11 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
return
;
return
;
}
}
get_ptr
(
&
blob
);
get_ptr
(
&
blob
);
Geometry
gobj
;
Geometry_buffer
buffer
;
gobj
.
create_from_wkb
(
blob
+
SRID_SIZE
,
blob_length
-
SRID_SIZE
);
Geometry
*
gobj
;
if
(
gobj
.
get_mbr
(
&
mbr
,
&
dummy
))
gobj
=
Geometry
::
create_from_wkb
(
&
buffer
,
blob
+
SRID_SIZE
,
blob_length
-
SRID_SIZE
);
if
(
gobj
->
get_mbr
(
&
mbr
,
&
dummy
))
bzero
(
buff
,
SIZEOF_STORED_DOUBLE
*
4
);
bzero
(
buff
,
SIZEOF_STORED_DOUBLE
*
4
);
else
else
{
{
...
@@ -5075,7 +5079,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
...
@@ -5075,7 +5079,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
if
(
length
<
SRID_SIZE
+
WKB_HEADER_SIZE
+
SIZEOF_STORED_DOUBLE
*
2
)
if
(
length
<
SRID_SIZE
+
WKB_HEADER_SIZE
+
SIZEOF_STORED_DOUBLE
*
2
)
goto
err
;
goto
err
;
wkb_type
=
uint4korr
(
from
+
WKB_HEADER_SIZE
);
wkb_type
=
uint4korr
(
from
+
WKB_HEADER_SIZE
);
if
(
wkb_type
<
(
uint32
)
Geometry
::
wkb
P
oint
||
if
(
wkb_type
<
(
uint32
)
Geometry
::
wkb
_p
oint
||
wkb_type
>
(
uint32
)
Geometry
::
wkb_end
)
wkb_type
>
(
uint32
)
Geometry
::
wkb_end
)
return
1
;
return
1
;
Field_blob
::
store_length
(
length
);
Field_blob
::
store_length
(
length
);
...
...
sql/item_geofunc.cc
View file @
6aa1cc4a
...
@@ -30,7 +30,8 @@
...
@@ -30,7 +30,8 @@
String
*
Item_func_geometry_from_text
::
val_str
(
String
*
str
)
String
*
Item_func_geometry_from_text
::
val_str
(
String
*
str
)
{
{
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
String
arg_val
;
String
arg_val
;
String
*
wkt
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
wkt
=
args
[
0
]
->
val_str
(
&
arg_val
);
Gis_read_stream
trs
(
wkt
->
c_ptr
(),
wkt
->
length
());
Gis_read_stream
trs
(
wkt
->
c_ptr
(),
wkt
->
length
());
...
@@ -43,7 +44,8 @@ String *Item_func_geometry_from_text::val_str(String *str)
...
@@ -43,7 +44,8 @@ String *Item_func_geometry_from_text::val_str(String *str)
return
0
;
return
0
;
str
->
length
(
0
);
str
->
length
(
0
);
str
->
q_append
(
srid
);
str
->
q_append
(
srid
);
if
((
null_value
=
(
args
[
0
]
->
null_value
||
geom
.
create_from_wkt
(
&
trs
,
str
,
0
))))
if
((
null_value
=
(
args
[
0
]
->
null_value
||
!
(
geom
=
Geometry
::
create_from_wkt
(
&
buffer
,
&
trs
,
str
,
0
)))))
return
0
;
return
0
;
return
str
;
return
str
;
}
}
...
@@ -59,7 +61,8 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
...
@@ -59,7 +61,8 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
{
{
String
arg_val
;
String
arg_val
;
String
*
wkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
wkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
uint32
srid
=
0
;
uint32
srid
=
0
;
if
((
arg_count
==
2
)
&&
!
args
[
1
]
->
null_value
)
if
((
arg_count
==
2
)
&&
!
args
[
1
]
->
null_value
)
...
@@ -69,9 +72,10 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
...
@@ -69,9 +72,10 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
return
0
;
return
0
;
str
->
length
(
0
);
str
->
length
(
0
);
str
->
q_append
(
srid
);
str
->
q_append
(
srid
);
if
((
null_value
=
(
args
[
0
]
->
null_value
||
if
((
null_value
=
geom
.
create_from_wkb
(
wkb
->
ptr
(),
wkb
->
length
())))
||
(
args
[
0
]
->
null_value
||
str
->
append
(
*
wkb
))
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
wkb
->
ptr
(),
wkb
->
length
()))
||
str
->
append
(
*
wkb
))))
return
0
;
return
0
;
return
str
;
return
str
;
}
}
...
@@ -87,16 +91,18 @@ String *Item_func_as_wkt::val_str(String *str)
...
@@ -87,16 +91,18 @@ String *Item_func_as_wkt::val_str(String *str)
{
{
String
arg_val
;
String
arg_val
;
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
=
NULL
;
const
char
*
dummy
;
const
char
*
dummy
;
if
((
null_value
=
(
args
[
0
]
->
null_value
||
if
((
null_value
=
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
(
args
[
0
]
->
null_value
||
swkb
->
length
()
-
SRID_SIZE
))))
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
)))))
return
0
;
return
0
;
str
->
length
(
0
);
str
->
length
(
0
);
if
((
null_value
=
geom
.
as_wkt
(
str
,
&
dummy
)))
if
((
null_value
=
geom
->
as_wkt
(
str
,
&
dummy
)))
return
0
;
return
0
;
return
str
;
return
str
;
...
@@ -113,11 +119,13 @@ String *Item_func_as_wkb::val_str(String *str)
...
@@ -113,11 +119,13 @@ String *Item_func_as_wkb::val_str(String *str)
{
{
String
arg_val
;
String
arg_val
;
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
if
((
null_value
=
(
args
[
0
]
->
null_value
||
if
((
null_value
=
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
(
args
[
0
]
->
null_value
||
swkb
->
length
()
-
SRID_SIZE
))))
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
)))))
return
0
;
return
0
;
str
->
copy
(
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
,
str
->
copy
(
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
,
...
@@ -135,15 +143,17 @@ void Item_func_as_wkb::fix_length_and_dec()
...
@@ -135,15 +143,17 @@ void Item_func_as_wkb::fix_length_and_dec()
String
*
Item_func_geometry_type
::
val_str
(
String
*
str
)
String
*
Item_func_geometry_type
::
val_str
(
String
*
str
)
{
{
String
*
swkb
=
args
[
0
]
->
val_str
(
str
);
String
*
swkb
=
args
[
0
]
->
val_str
(
str
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
=
NULL
;
if
((
null_value
=
(
args
[
0
]
->
null_value
||
if
((
null_value
=
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
(
args
[
0
]
->
null_value
||
swkb
->
length
()
-
SRID_SIZE
))))
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
)))))
return
0
;
return
0
;
/* String will not move */
/* String will not move */
str
->
set
(
geom
.
get_class_info
()
->
m_name
.
str
,
str
->
set
(
geom
->
get_class_info
()
->
m_name
.
str
,
geom
.
get_class_info
()
->
m_name
.
length
,
geom
->
get_class_info
()
->
m_name
.
length
,
default_charset
());
default_charset
());
return
str
;
return
str
;
}
}
...
@@ -153,12 +163,14 @@ String *Item_func_envelope::val_str(String *str)
...
@@ -153,12 +163,14 @@ String *Item_func_envelope::val_str(String *str)
{
{
String
arg_val
;
String
arg_val
;
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
=
NULL
;
uint32
srid
;
uint32
srid
;
if
((
null_value
=
args
[
0
]
->
null_value
||
if
((
null_value
=
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
args
[
0
]
->
null_value
||
swkb
->
length
()
-
SRID_SIZE
)))
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
))))
return
0
;
return
0
;
srid
=
uint4korr
(
swkb
->
ptr
());
srid
=
uint4korr
(
swkb
->
ptr
());
...
@@ -166,7 +178,7 @@ String *Item_func_envelope::val_str(String *str)
...
@@ -166,7 +178,7 @@ String *Item_func_envelope::val_str(String *str)
if
(
str
->
reserve
(
SRID_SIZE
,
512
))
if
(
str
->
reserve
(
SRID_SIZE
,
512
))
return
0
;
return
0
;
str
->
q_append
(
srid
);
str
->
q_append
(
srid
);
return
(
null_value
=
geom
.
envelope
(
str
))
?
0
:
str
;
return
(
null_value
=
geom
->
envelope
(
str
))
?
0
:
str
;
}
}
...
@@ -174,13 +186,13 @@ String *Item_func_centroid::val_str(String *str)
...
@@ -174,13 +186,13 @@ String *Item_func_centroid::val_str(String *str)
{
{
String
arg_val
;
String
arg_val
;
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
=
NULL
;
uint32
srid
;
uint32
srid
;
if
((
null_value
=
args
[
0
]
->
null_value
||
if
((
null_value
=
args
[
0
]
->
null_value
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
length
()
-
SRID_SIZE
))))
!
GEOM_METHOD_PRESENT
(
geom
,
centroid
)))
return
0
;
return
0
;
if
(
str
->
reserve
(
SRID_SIZE
,
512
))
if
(
str
->
reserve
(
SRID_SIZE
,
512
))
...
@@ -189,7 +201,7 @@ String *Item_func_centroid::val_str(String *str)
...
@@ -189,7 +201,7 @@ String *Item_func_centroid::val_str(String *str)
srid
=
uint4korr
(
swkb
->
ptr
());
srid
=
uint4korr
(
swkb
->
ptr
());
str
->
q_append
(
srid
);
str
->
q_append
(
srid
);
return
(
null_value
=
test
(
geom
.
centroid
(
str
)))
?
0
:
str
;
return
(
null_value
=
test
(
geom
->
centroid
(
str
)))
?
0
:
str
;
}
}
...
@@ -201,12 +213,14 @@ String *Item_func_spatial_decomp::val_str(String *str)
...
@@ -201,12 +213,14 @@ String *Item_func_spatial_decomp::val_str(String *str)
{
{
String
arg_val
;
String
arg_val
;
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
=
NULL
;
uint32
srid
;
uint32
srid
;
if
((
null_value
=
(
args
[
0
]
->
null_value
||
if
((
null_value
=
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
(
args
[
0
]
->
null_value
||
swkb
->
length
()
-
SRID_SIZE
))))
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
)))))
return
0
;
return
0
;
srid
=
uint4korr
(
swkb
->
ptr
());
srid
=
uint4korr
(
swkb
->
ptr
());
...
@@ -216,17 +230,17 @@ String *Item_func_spatial_decomp::val_str(String *str)
...
@@ -216,17 +230,17 @@ String *Item_func_spatial_decomp::val_str(String *str)
str
->
q_append
(
srid
);
str
->
q_append
(
srid
);
switch
(
decomp_func
)
{
switch
(
decomp_func
)
{
case
SP_STARTPOINT
:
case
SP_STARTPOINT
:
if
(
!
GEOM_METHOD_PRESENT
(
geom
,
start_point
)
||
geom
.
start_point
(
str
))
if
(
geom
->
start_point
(
str
))
goto
err
;
goto
err
;
break
;
break
;
case
SP_ENDPOINT
:
case
SP_ENDPOINT
:
if
(
!
GEOM_METHOD_PRESENT
(
geom
,
end_point
)
||
geom
.
end_point
(
str
))
if
(
geom
->
end_point
(
str
))
goto
err
;
goto
err
;
break
;
break
;
case
SP_EXTERIORRING
:
case
SP_EXTERIORRING
:
if
(
!
GEOM_METHOD_PRESENT
(
geom
,
exterior_ring
)
||
geom
.
exterior_ring
(
str
))
if
(
geom
->
exterior_ring
(
str
))
goto
err
;
goto
err
;
break
;
break
;
...
@@ -246,12 +260,14 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
...
@@ -246,12 +260,14 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
String
arg_val
;
String
arg_val
;
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
arg_val
);
long
n
=
(
long
)
args
[
1
]
->
val_int
();
long
n
=
(
long
)
args
[
1
]
->
val_int
();
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
=
NULL
;
uint32
srid
;
uint32
srid
;
if
((
null_value
=
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
if
((
null_value
=
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
swkb
->
length
()
-
SRID_SIZE
))))
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
)))))
return
0
;
return
0
;
if
(
str
->
reserve
(
SRID_SIZE
,
512
))
if
(
str
->
reserve
(
SRID_SIZE
,
512
))
...
@@ -262,18 +278,17 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
...
@@ -262,18 +278,17 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
switch
(
decomp_func_n
)
switch
(
decomp_func_n
)
{
{
case
SP_POINTN
:
case
SP_POINTN
:
if
(
!
GEOM_METHOD_PRESENT
(
geom
,
point_n
)
||
geom
.
point_n
(
n
,
str
))
if
(
geom
->
point_n
(
n
,
str
))
goto
err
;
goto
err
;
break
;
break
;
case
SP_GEOMETRYN
:
case
SP_GEOMETRYN
:
if
(
!
GEOM_METHOD_PRESENT
(
geom
,
geometry_n
)
||
geom
.
geometry_n
(
n
,
str
))
if
(
geom
->
geometry_n
(
n
,
str
))
goto
err
;
goto
err
;
break
;
break
;
case
SP_INTERIORRINGN
:
case
SP_INTERIORRINGN
:
if
(
!
GEOM_METHOD_PRESENT
(
geom
,
interior_ring_n
)
||
if
(
geom
->
interior_ring_n
(
n
,
str
))
geom
.
interior_ring_n
(
n
,
str
))
goto
err
;
goto
err
;
break
;
break
;
...
@@ -309,8 +324,8 @@ String *Item_func_point::val_str(String *str)
...
@@ -309,8 +324,8 @@ String *Item_func_point::val_str(String *str)
return
0
;
return
0
;
str
->
length
(
0
);
str
->
length
(
0
);
str
->
q_append
((
char
)
Geometry
::
wkb
NDR
);
str
->
q_append
((
char
)
Geometry
::
wkb
_ndr
);
str
->
q_append
((
uint32
)
Geometry
::
wkb
P
oint
);
str
->
q_append
((
uint32
)
Geometry
::
wkb
_p
oint
);
str
->
q_append
(
x
);
str
->
q_append
(
x
);
str
->
q_append
(
y
);
str
->
q_append
(
y
);
return
str
;
return
str
;
...
@@ -336,7 +351,7 @@ String *Item_func_spatial_collection::val_str(String *str)
...
@@ -336,7 +351,7 @@ String *Item_func_spatial_collection::val_str(String *str)
if
(
str
->
reserve
(
1
+
4
+
4
,
512
))
if
(
str
->
reserve
(
1
+
4
+
4
,
512
))
goto
err
;
goto
err
;
str
->
q_append
((
char
)
Geometry
::
wkb
NDR
);
str
->
q_append
((
char
)
Geometry
::
wkb
_ndr
);
str
->
q_append
((
uint32
)
coll_type
);
str
->
q_append
((
uint32
)
coll_type
);
str
->
q_append
((
uint32
)
arg_count
);
str
->
q_append
((
uint32
)
arg_count
);
...
@@ -346,7 +361,7 @@ String *Item_func_spatial_collection::val_str(String *str)
...
@@ -346,7 +361,7 @@ String *Item_func_spatial_collection::val_str(String *str)
if
(
args
[
i
]
->
null_value
)
if
(
args
[
i
]
->
null_value
)
goto
err
;
goto
err
;
if
(
coll_type
==
Geometry
::
wkb
GeometryC
ollection
)
if
(
coll_type
==
Geometry
::
wkb
_geometryc
ollection
)
{
{
/*
/*
In the case of GeometryCollection we don't need any checkings
In the case of GeometryCollection we don't need any checkings
...
@@ -375,19 +390,19 @@ String *Item_func_spatial_collection::val_str(String *str)
...
@@ -375,19 +390,19 @@ String *Item_func_spatial_collection::val_str(String *str)
goto
err
;
goto
err
;
switch
(
coll_type
)
{
switch
(
coll_type
)
{
case
Geometry
:
:
wkb
MultiP
oint
:
case
Geometry
:
:
wkb
_multip
oint
:
case
Geometry
:
:
wkb
MultiLineS
tring
:
case
Geometry
:
:
wkb
_multilines
tring
:
case
Geometry
:
:
wkb
MultiP
olygon
:
case
Geometry
:
:
wkb
_multip
olygon
:
if
(
len
<
WKB_HEADER_SIZE
||
if
(
len
<
WKB_HEADER_SIZE
||
str
->
append
(
data
-
WKB_HEADER_SIZE
,
len
+
WKB_HEADER_SIZE
,
512
))
str
->
append
(
data
-
WKB_HEADER_SIZE
,
len
+
WKB_HEADER_SIZE
,
512
))
goto
err
;
goto
err
;
break
;
break
;
case
Geometry
:
:
wkb
LineS
tring
:
case
Geometry
:
:
wkb
_lines
tring
:
if
(
str
->
append
(
data
,
POINT_DATA_SIZE
,
512
))
if
(
str
->
append
(
data
,
POINT_DATA_SIZE
,
512
))
goto
err
;
goto
err
;
break
;
break
;
case
Geometry
:
:
wkb
P
olygon
:
case
Geometry
:
:
wkb
_p
olygon
:
{
{
uint32
n_points
;
uint32
n_points
;
double
x1
,
y1
,
x2
,
y2
;
double
x1
,
y1
,
x2
,
y2
;
...
@@ -439,18 +454,20 @@ longlong Item_func_spatial_rel::val_int()
...
@@ -439,18 +454,20 @@ longlong Item_func_spatial_rel::val_int()
{
{
String
*
res1
=
args
[
0
]
->
val_str
(
&
tmp_value1
);
String
*
res1
=
args
[
0
]
->
val_str
(
&
tmp_value1
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_value2
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_value2
);
Geometry
g1
,
g2
;
Geometry_buffer
buffer1
,
buffer2
;
Geometry
*
g1
,
*
g2
;
MBR
mbr1
,
mbr2
;
MBR
mbr1
,
mbr2
;
const
char
*
dummy
;
const
char
*
dummy
;
if
((
null_value
=
(
args
[
0
]
->
null_value
||
if
((
null_value
=
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
args
[
1
]
->
null_value
||
g1
.
create_from_wkb
(
res1
->
ptr
()
+
SRID_SIZE
,
!
(
g1
=
Geometry
::
create_from_wkb
(
&
buffer1
,
res1
->
ptr
()
+
SRID_SIZE
,
res1
->
length
()
-
SRID_SIZE
)
||
res1
->
length
()
-
SRID_SIZE
)
)
||
g2
.
create_from_wkb
(
res2
->
ptr
()
+
SRID_SIZE
,
!
(
g2
=
Geometry
::
create_from_wkb
(
&
buffer2
,
res2
->
ptr
()
+
SRID_SIZE
,
res2
->
length
()
-
SRID_SIZE
)
||
res2
->
length
()
-
SRID_SIZE
)
)
||
g1
.
get_mbr
(
&
mbr1
,
&
dummy
)
||
g1
->
get_mbr
(
&
mbr1
,
&
dummy
)
||
g2
.
get_mbr
(
&
mbr2
,
&
dummy
))))
g2
->
get_mbr
(
&
mbr2
,
&
dummy
))))
return
0
;
return
0
;
switch
(
spatial_rel
)
{
switch
(
spatial_rel
)
{
...
@@ -503,15 +520,16 @@ longlong Item_func_isclosed::val_int()
...
@@ -503,15 +520,16 @@ longlong Item_func_isclosed::val_int()
{
{
String
tmp
;
String
tmp
;
String
*
swkb
=
args
[
0
]
->
val_str
(
&
tmp
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
tmp
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
int
isclosed
=
0
;
// In case of error
int
isclosed
=
0
;
// In case of error
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
args
[
0
]
->
null_value
||
args
[
0
]
->
null_value
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
swkb
->
length
()
-
SRID_SIZE
)
||
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
is_closed
)
||
swkb
->
length
()
-
SRID_SIZE
)
)
||
geom
.
is_closed
(
&
isclosed
));
geom
->
is_closed
(
&
isclosed
));
return
(
longlong
)
isclosed
;
return
(
longlong
)
isclosed
;
}
}
...
@@ -525,14 +543,16 @@ longlong Item_func_dimension::val_int()
...
@@ -525,14 +543,16 @@ longlong Item_func_dimension::val_int()
{
{
uint32
dim
=
0
;
// In case of error
uint32
dim
=
0
;
// In case of error
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
const
char
*
dummy
;
const
char
*
dummy
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
args
[
0
]
->
null_value
||
args
[
0
]
->
null_value
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
geom
.
dimension
(
&
dim
,
&
dummy
));
swkb
->
length
()
-
SRID_SIZE
))
||
geom
->
dimension
(
&
dim
,
&
dummy
));
return
(
longlong
)
dim
;
return
(
longlong
)
dim
;
}
}
...
@@ -541,13 +561,14 @@ longlong Item_func_numinteriorring::val_int()
...
@@ -541,13 +561,14 @@ longlong Item_func_numinteriorring::val_int()
{
{
uint32
num
=
0
;
// In case of error
uint32
num
=
0
;
// In case of error
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
num_interior_ring
)
||
swkb
->
length
()
-
SRID_SIZE
))
||
geom
.
num_interior_ring
(
&
num
));
geom
->
num_interior_ring
(
&
num
));
return
(
longlong
)
num
;
return
(
longlong
)
num
;
}
}
...
@@ -556,13 +577,14 @@ longlong Item_func_numgeometries::val_int()
...
@@ -556,13 +577,14 @@ longlong Item_func_numgeometries::val_int()
{
{
uint32
num
=
0
;
// In case of errors
uint32
num
=
0
;
// In case of errors
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
num_geometries
)
||
swkb
->
length
()
-
SRID_SIZE
))
||
geom
.
num_geometries
(
&
num
));
geom
->
num_geometries
(
&
num
));
return
(
longlong
)
num
;
return
(
longlong
)
num
;
}
}
...
@@ -571,14 +593,15 @@ longlong Item_func_numpoints::val_int()
...
@@ -571,14 +593,15 @@ longlong Item_func_numpoints::val_int()
{
{
uint32
num
=
0
;
// In case of errors
uint32
num
=
0
;
// In case of errors
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
args
[
0
]
->
null_value
||
args
[
0
]
->
null_value
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
num_points
)
||
swkb
->
length
()
-
SRID_SIZE
)
)
||
geom
.
num_points
(
&
num
));
geom
->
num_points
(
&
num
));
return
(
longlong
)
num
;
return
(
longlong
)
num
;
}
}
...
@@ -587,13 +610,14 @@ double Item_func_x::val()
...
@@ -587,13 +610,14 @@ double Item_func_x::val()
{
{
double
res
=
0.0
;
// In case of errors
double
res
=
0.0
;
// In case of errors
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
get_x
)
||
swkb
->
length
()
-
SRID_SIZE
))
||
geom
.
get_x
(
&
res
));
geom
->
get_x
(
&
res
));
return
res
;
return
res
;
}
}
...
@@ -602,13 +626,14 @@ double Item_func_y::val()
...
@@ -602,13 +626,14 @@ double Item_func_y::val()
{
{
double
res
=
0
;
// In case of errors
double
res
=
0
;
// In case of errors
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
get_y
)
||
swkb
->
length
()
-
SRID_SIZE
))
||
geom
.
get_y
(
&
res
));
geom
->
get_y
(
&
res
));
return
res
;
return
res
;
}
}
...
@@ -617,14 +642,15 @@ double Item_func_area::val()
...
@@ -617,14 +642,15 @@ double Item_func_area::val()
{
{
double
res
=
0
;
// In case of errors
double
res
=
0
;
// In case of errors
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
const
char
*
dummy
;
const
char
*
dummy
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
area
)
||
swkb
->
length
()
-
SRID_SIZE
))
||
geom
.
area
(
&
res
,
&
dummy
));
geom
->
area
(
&
res
,
&
dummy
));
return
res
;
return
res
;
}
}
...
@@ -632,23 +658,26 @@ double Item_func_glength::val()
...
@@ -632,23 +658,26 @@ double Item_func_glength::val()
{
{
double
res
=
0
;
// In case of errors
double
res
=
0
;
// In case of errors
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
null_value
=
(
!
swkb
||
null_value
=
(
!
swkb
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
length
()
-
SRID_SIZE
)
||
swkb
->
ptr
()
+
SRID_SIZE
,
!
GEOM_METHOD_PRESENT
(
geom
,
length
)
||
swkb
->
length
()
-
SRID_SIZE
))
||
geom
.
length
(
&
res
));
geom
->
length
(
&
res
));
return
res
;
return
res
;
}
}
longlong
Item_func_srid
::
val_int
()
longlong
Item_func_srid
::
val_int
()
{
{
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
String
*
swkb
=
args
[
0
]
->
val_str
(
&
value
);
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
null_value
=
(
!
swkb
||
null_value
=
!
swkb
||
geom
.
create_from_wkb
(
swkb
->
ptr
()
+
SRID_SIZE
,
!
(
geom
=
Geometry
::
create_from_wkb
(
&
buffer
,
swkb
->
ptr
()
+
SRID_SIZE
,
swkb
->
length
()
-
SRID_SIZE
));
swkb
->
length
()
-
SRID_SIZE
));
if
(
null_value
)
if
(
null_value
)
return
0
;
return
0
;
...
...
sql/spatial.cc
View file @
6aa1cc4a
...
@@ -19,91 +19,105 @@
...
@@ -19,91 +19,105 @@
/***************************** Gis_class_info *******************************/
/***************************** Gis_class_info *******************************/
#define IMPLEMENT_GEOM(class_name, type_id, name) \
Geometry
::
Class_info
*
Geometry
::
ci_collection
[
Geometry
::
wkb_end
]
=
{ \
{
(GF_InitFromText) &class_name::init_from_wkt, \
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
(GF_GetDataAsText) &class_name::get_data_as_wkt, \
(GF_GetDataSize) &class_name::get_data_size, \
(GF_GetMBR) &class_name::get_mbr, \
(GF_GetD) &class_name::get_x, \
(GF_GetD) &class_name::get_y, \
(GF_GetD) &class_name::length, \
(GF_GetD_AND_END) &class_name::area, \
(GF_GetI) &class_name::is_closed, \
(GF_GetUI) &class_name::num_interior_ring, \
(GF_GetUI) &class_name::num_points, \
(GF_GetUI) &class_name::num_geometries, \
(GF_GetUI_AND_END) &class_name::dimension, \
(GF_GetWS) &class_name::start_point, \
(GF_GetWS) &class_name::end_point, \
(GF_GetWS) &class_name::exterior_ring, \
(GF_GetWS) &class_name::centroid, \
(GF_GetUIWS) &class_name::point_n, \
(GF_GetUIWS) &class_name::interior_ring_n, \
(GF_GetUIWS) &class_name::geometry_n, \
name, \
class_name::type_id, \
NULL \
}
static
LEX_STRING_WITH_INIT
point_name
(
"POINT"
,
5
);
static
LEX_STRING_WITH_INIT
linestring_name
(
"LINESTRING"
,
10
);
static
LEX_STRING_WITH_INIT
polygon_name
(
"POLYGON"
,
7
);
static
LEX_STRING_WITH_INIT
multipoint_name
(
"MULTIPOINT"
,
10
);
static
LEX_STRING_WITH_INIT
multilinestring_name
(
"MULTILINESTRING"
,
15
);
static
LEX_STRING_WITH_INIT
multipolygon_name
(
"MULTIPOLYGON"
,
12
);
static
LEX_STRING_WITH_INIT
geometrycollection_name
(
"GEOMETRYCOLLECTION"
,
18
);
static
Geometry
::
Gis_class_info
ci_collection
[]
=
{
IMPLEMENT_GEOM
(
Gis_point
,
wkbPoint
,
point_name
),
IMPLEMENT_GEOM
(
Gis_line_string
,
wkbLineString
,
linestring_name
),
IMPLEMENT_GEOM
(
Gis_polygon
,
wkbPolygon
,
polygon_name
),
IMPLEMENT_GEOM
(
Gis_multi_point
,
wkbMultiPoint
,
multipoint_name
),
IMPLEMENT_GEOM
(
Gis_multi_line_stringg
,
wkbMultiLineString
,
multilinestring_name
),
IMPLEMENT_GEOM
(
Gis_multi_polygon
,
wkbMultiPolygon
,
multipolygon_name
),
IMPLEMENT_GEOM
(
Gis_geometry_collection
,
wkbGeometryCollection
,
geometrycollection_name
)
};
};
static
Geometry
::
Gis_class_info
*
ci_collection_end
=
static
Geometry
::
Class_info
*
*
ci_collection_end
=
(
ci_collection
+
array_elements
(
ci_collection
))
;
Geometry
::
ci_collection
+
Geometry
::
wkb_end
;
Geometry
::
Class_info
::
Class_info
(
const
char
*
name
,
int
type_id
,
void
(
*
create_func
)(
void
*
))
:
m_name
(
name
,
strlen
(
name
)),
m_type_id
(
type_id
),
m_create_func
(
create_func
)
{
ci_collection
[
type_id
]
=
this
;
}
/***************************** Geometry *******************************/
static
void
create_point
(
void
*
buffer
)
{
new
(
buffer
)
Gis_point
;
}
Geometry
::
Gis_class_info
*
Geometry
::
find_class
(
int
type_id
)
static
void
create_linestring
(
void
*
buffer
)
{
{
for
(
Gis_class_info
*
cur_rt
=
ci_collection
;
cur_rt
<
ci_collection_end
;
cur_rt
++
)
new
(
buffer
)
Gis_line_string
;
{
}
if
(
cur_rt
->
m_type_id
==
type_id
)
return
cur_rt
;
static
void
create_polygon
(
void
*
buffer
)
}
{
return
0
;
new
(
buffer
)
Gis_polygon
;
}
static
void
create_multipoint
(
void
*
buffer
)
{
new
(
buffer
)
Gis_multi_point
;
}
}
static
void
create_multipolygon
(
void
*
buffer
)
{
new
(
buffer
)
Gis_multi_polygon
;
}
static
void
create_multilinestring
(
void
*
buffer
)
{
new
(
buffer
)
Gis_multi_line_string
;
}
Geometry
::
Gis_class_info
*
Geometry
::
find_class
(
const
char
*
name
,
uint32
len
)
static
void
create_geometrycollection
(
void
*
buffer
)
{
{
for
(
Gis_class_info
*
cur_rt
=
ci_collection
;
cur_rt
<
ci_collection_end
;
cur_rt
++
)
new
(
buffer
)
Gis_geometry_collection
;
}
static
Geometry
::
Class_info
point_class
(
"POINT"
,
Geometry
::
wkb_point
,
create_point
);
static
Geometry
::
Class_info
linestring_class
(
"LINESTRING"
,
Geometry
::
wkb_linestring
,
create_linestring
);
static
Geometry
::
Class_info
polygon_class
(
"POLYGON"
,
Geometry
::
wkb_polygon
,
create_polygon
);
static
Geometry
::
Class_info
multipoint_class
(
"MULTIPOINT"
,
Geometry
::
wkb_multipoint
,
create_multipoint
);
static
Geometry
::
Class_info
multilinestring_class
(
"MULTILINESTRING"
,
Geometry
::
wkb_multilinestring
,
create_multilinestring
);
static
Geometry
::
Class_info
multipolygon_class
(
"MULTIPOLYGON"
,
Geometry
::
wkb_multipolygon
,
create_multipolygon
);
static
Geometry
::
Class_info
geometrycollection_class
(
"GEOMETRYCOLLECTION"
,
Geometry
::
wkb_geometrycollection
,
create_geometrycollection
);
/***************************** Geometry *******************************/
Geometry
::
Class_info
*
Geometry
::
find_class
(
const
char
*
name
,
uint32
len
)
{
for
(
Class_info
**
cur_rt
=
ci_collection
;
cur_rt
<
ci_collection_end
;
cur_rt
++
)
{
{
if
((
cur_rt
->
m_name
.
length
==
len
)
&&
if
(
*
cur_rt
&&
((
*
cur_rt
)
->
m_name
.
length
==
len
)
&&
(
my_strnncoll
(
&
my_charset_latin1
,
(
my_strnncoll
(
&
my_charset_latin1
,
(
const
uchar
*
)
cur_rt
->
m_name
.
str
,
len
,
(
const
uchar
*
)
(
*
cur_rt
)
->
m_name
.
str
,
len
,
(
const
uchar
*
)
name
,
len
)
==
0
))
(
const
uchar
*
)
name
,
len
)
==
0
))
return
cur_rt
;
return
*
cur_rt
;
}
}
return
0
;
return
0
;
}
}
Geometry
*
Geometry
::
create_from_wkb
(
Geometry_buffer
*
buffer
,
int
Geometry
::
create_from_wkb
(
const
char
*
data
,
uint32
data_len
)
const
char
*
data
,
uint32
data_len
)
{
{
uint32
geom_type
;
uint32
geom_type
;
Geometry
*
result
;
if
(
data_len
<
1
+
4
)
if
(
data_len
<
1
+
4
)
return
1
;
return
NULL
;
data
++
;
data
++
;
/*
/*
FIXME: check byte ordering
FIXME: check byte ordering
...
@@ -111,39 +125,44 @@ int Geometry::create_from_wkb(const char *data, uint32 data_len)
...
@@ -111,39 +125,44 @@ int Geometry::create_from_wkb(const char *data, uint32 data_len)
*/
*/
geom_type
=
uint4korr
(
data
);
geom_type
=
uint4korr
(
data
);
data
+=
4
;
data
+=
4
;
if
(
!
(
m_vmt
=
find_class
(
(
int
)
geom_type
)))
if
(
!
(
result
=
create_by_typeid
(
buffer
,
(
int
)
geom_type
)))
return
1
;
return
NULL
;
m_data
=
data
;
result
->
m_data
=
data
;
m_data_end
=
data
+
data_len
;
result
->
m_data_end
=
data
+
data_len
;
return
0
;
return
result
;
}
}
int
Geometry
::
create_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkt
,
Geometry
*
Geometry
::
create_from_wkt
(
Geometry_buffer
*
buffer
,
Gis_read_stream
*
trs
,
String
*
wkt
,
bool
init_stream
)
bool
init_stream
)
{
{
LEX_STRING
name
;
LEX_STRING
name
;
Class_info
*
ci
;
if
(
trs
->
get_next_word
(
&
name
))
if
(
trs
->
get_next_word
(
&
name
))
{
{
trs
->
set_error_msg
(
"Geometry name expected"
);
trs
->
set_error_msg
(
"Geometry name expected"
);
return
1
;
return
NULL
;
}
}
if
(
!
(
m_vmt
=
find_class
(
name
.
str
,
name
.
length
))
||
if
(
!
(
ci
=
find_class
(
name
.
str
,
name
.
length
))
||
wkt
->
reserve
(
1
+
4
,
512
))
wkt
->
reserve
(
1
+
4
,
512
))
return
1
;
return
NULL
;
wkt
->
q_append
((
char
)
wkbNDR
);
(
*
ci
->
m_create_func
)((
void
*
)
buffer
);
wkt
->
q_append
((
uint32
)
get_class_info
()
->
m_type_id
);
Geometry
*
result
=
(
Geometry
*
)
buffer
;
wkt
->
q_append
((
char
)
wkb_ndr
);
wkt
->
q_append
((
uint32
)
result
->
get_class_info
()
->
m_type_id
);
if
(
trs
->
check_next_symbol
(
'('
)
||
if
(
trs
->
check_next_symbol
(
'('
)
||
init_from_wkt
(
trs
,
wkt
)
||
result
->
init_from_wkt
(
trs
,
wkt
)
||
trs
->
check_next_symbol
(
')'
))
trs
->
check_next_symbol
(
')'
))
return
1
;
return
NULL
;
if
(
init_stream
)
if
(
init_stream
)
{
{
init_from_wkb
(
wkt
->
ptr
(),
wkt
->
length
());
result
->
init_from_wkb
(
wkt
->
ptr
(),
wkt
->
length
());
shift_wkb_header
();
result
->
shift_wkb_header
();
}
}
return
0
;
return
result
;
}
}
...
@@ -155,8 +174,8 @@ bool Geometry::envelope(String *result) const
...
@@ -155,8 +174,8 @@ bool Geometry::envelope(String *result) const
if
(
get_mbr
(
&
mbr
,
&
end
)
||
result
->
reserve
(
1
+
4
*
3
+
SIZEOF_STORED_DOUBLE
*
10
))
if
(
get_mbr
(
&
mbr
,
&
end
)
||
result
->
reserve
(
1
+
4
*
3
+
SIZEOF_STORED_DOUBLE
*
10
))
return
1
;
return
1
;
result
->
q_append
((
char
)
wkb
NDR
);
result
->
q_append
((
char
)
wkb
_ndr
);
result
->
q_append
((
uint32
)
wkb
P
olygon
);
result
->
q_append
((
uint32
)
wkb
_p
olygon
);
result
->
q_append
((
uint32
)
1
);
result
->
q_append
((
uint32
)
1
);
result
->
q_append
((
uint32
)
5
);
result
->
q_append
((
uint32
)
5
);
result
->
q_append
(
mbr
.
xmin
);
result
->
q_append
(
mbr
.
xmin
);
...
@@ -187,13 +206,13 @@ bool Geometry::envelope(String *result) const
...
@@ -187,13 +206,13 @@ bool Geometry::envelope(String *result) const
1 Can't reallocate 'result'
1 Can't reallocate 'result'
*/
*/
bool
Geometry
::
create_point
(
String
*
result
,
const
char
*
data
)
bool
Geometry
::
create_point
(
String
*
result
,
const
char
*
data
)
const
{
{
if
(
no_data
(
data
,
SIZEOF_STORED_DOUBLE
*
2
)
||
if
(
no_data
(
data
,
SIZEOF_STORED_DOUBLE
*
2
)
||
result
->
reserve
(
1
+
4
+
SIZEOF_STORED_DOUBLE
*
2
))
result
->
reserve
(
1
+
4
+
SIZEOF_STORED_DOUBLE
*
2
))
return
1
;
return
1
;
result
->
q_append
((
char
)
wkb
NDR
);
result
->
q_append
((
char
)
wkb
_ndr
);
result
->
q_append
((
uint32
)
wkb
P
oint
);
result
->
q_append
((
uint32
)
wkb
_p
oint
);
/* Copy two double in same format */
/* Copy two double in same format */
result
->
q_append
(
data
,
SIZEOF_STORED_DOUBLE
*
2
);
result
->
q_append
(
data
,
SIZEOF_STORED_DOUBLE
*
2
);
return
0
;
return
0
;
...
@@ -213,13 +232,13 @@ bool Geometry::create_point(String *result, const char *data)
...
@@ -213,13 +232,13 @@ bool Geometry::create_point(String *result, const char *data)
1 Can't reallocate 'result'
1 Can't reallocate 'result'
*/
*/
bool
Geometry
::
create_point
(
String
*
result
,
double
x
,
double
y
)
bool
Geometry
::
create_point
(
String
*
result
,
double
x
,
double
y
)
const
{
{
if
(
result
->
reserve
(
1
+
4
+
SIZEOF_STORED_DOUBLE
*
2
))
if
(
result
->
reserve
(
1
+
4
+
SIZEOF_STORED_DOUBLE
*
2
))
return
1
;
return
1
;
result
->
q_append
((
char
)
wkb
NDR
);
result
->
q_append
((
char
)
wkb
_ndr
);
result
->
q_append
((
uint32
)
wkb
P
oint
);
result
->
q_append
((
uint32
)
wkb
_p
oint
);
result
->
q_append
(
x
);
result
->
q_append
(
x
);
result
->
q_append
(
y
);
result
->
q_append
(
y
);
return
0
;
return
0
;
...
@@ -240,7 +259,7 @@ bool Geometry::create_point(String *result, double x, double y)
...
@@ -240,7 +259,7 @@ bool Geometry::create_point(String *result, double x, double y)
*/
*/
const
char
*
Geometry
::
append_points
(
String
*
txt
,
uint32
n_points
,
const
char
*
Geometry
::
append_points
(
String
*
txt
,
uint32
n_points
,
const
char
*
data
,
uint32
offset
)
const
char
*
data
,
uint32
offset
)
const
{
{
while
(
n_points
--
)
while
(
n_points
--
)
{
{
...
@@ -317,7 +336,7 @@ bool Gis_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -317,7 +336,7 @@ bool Gis_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
}
bool
Gis_point
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
bool
Gis_point
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
{
{
double
x
,
y
;
double
x
,
y
;
if
(
get_xy
(
&
x
,
&
y
))
if
(
get_xy
(
&
x
,
&
y
))
...
@@ -332,7 +351,7 @@ bool Gis_point::get_data_as_wkt(String *txt, const char **end)
...
@@ -332,7 +351,7 @@ bool Gis_point::get_data_as_wkt(String *txt, const char **end)
}
}
int
Gis_point
::
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
bool
Gis_point
::
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
{
{
double
x
,
y
;
double
x
,
y
;
if
(
get_xy
(
&
x
,
&
y
))
if
(
get_xy
(
&
x
,
&
y
))
...
@@ -342,6 +361,11 @@ int Gis_point::get_mbr(MBR *mbr, const char **end) const
...
@@ -342,6 +361,11 @@ int Gis_point::get_mbr(MBR *mbr, const char **end) const
return
0
;
return
0
;
}
}
const
Geometry
::
Class_info
*
Gis_point
::
get_class_info
()
const
{
return
&
point_class
;
}
/***************************** LineString *******************************/
/***************************** LineString *******************************/
...
@@ -381,7 +405,7 @@ bool Gis_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -381,7 +405,7 @@ bool Gis_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
}
bool
Gis_line_string
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
bool
Gis_line_string
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
{
{
uint32
n_points
;
uint32
n_points
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -419,7 +443,7 @@ bool Gis_line_string::get_mbr(MBR *mbr, const char **end) const
...
@@ -419,7 +443,7 @@ bool Gis_line_string::get_mbr(MBR *mbr, const char **end) const
}
}
bool
Gis_line_string
::
length
(
double
*
len
)
const
int
Gis_line_string
::
length
(
double
*
len
)
const
{
{
uint32
n_points
;
uint32
n_points
;
double
prev_x
,
prev_y
;
double
prev_x
,
prev_y
;
...
@@ -451,7 +475,7 @@ bool Gis_line_string::length(double *len) const
...
@@ -451,7 +475,7 @@ bool Gis_line_string::length(double *len) const
}
}
bool
Gis_line_string
::
is_closed
(
int
*
closed
)
const
int
Gis_line_string
::
is_closed
(
int
*
closed
)
const
{
{
uint32
n_points
;
uint32
n_points
;
double
x1
,
y1
,
x2
,
y2
;
double
x1
,
y1
,
x2
,
y2
;
...
@@ -478,21 +502,21 @@ bool Gis_line_string::is_closed(int *closed) const
...
@@ -478,21 +502,21 @@ bool Gis_line_string::is_closed(int *closed) const
}
}
bool
Gis_line_string
::
num_points
(
uint32
*
n_points
)
const
int
Gis_line_string
::
num_points
(
uint32
*
n_points
)
const
{
{
*
n_points
=
uint4korr
(
m_data
);
*
n_points
=
uint4korr
(
m_data
);
return
0
;
return
0
;
}
}
bool
Gis_line_string
::
start_point
(
String
*
result
)
int
Gis_line_string
::
start_point
(
String
*
result
)
const
{
{
/* +4 is for skipping over number of points */
/* +4 is for skipping over number of points */
return
create_point
(
result
,
m_data
+
4
);
return
create_point
(
result
,
m_data
+
4
);
}
}
bool
Gis_line_string
::
end_point
(
String
*
result
)
int
Gis_line_string
::
end_point
(
String
*
result
)
const
{
{
uint32
n_points
;
uint32
n_points
;
if
(
no_data
(
m_data
,
4
))
if
(
no_data
(
m_data
,
4
))
...
@@ -502,7 +526,7 @@ bool Gis_line_string::end_point(String *result)
...
@@ -502,7 +526,7 @@ bool Gis_line_string::end_point(String *result)
}
}
bool
Gis_line_string
::
point_n
(
uint32
num
,
String
*
result
)
int
Gis_line_string
::
point_n
(
uint32
num
,
String
*
result
)
const
{
{
uint32
n_points
;
uint32
n_points
;
if
(
no_data
(
m_data
,
4
))
if
(
no_data
(
m_data
,
4
))
...
@@ -514,6 +538,11 @@ bool Gis_line_string::point_n(uint32 num, String *result)
...
@@ -514,6 +538,11 @@ bool Gis_line_string::point_n(uint32 num, String *result)
return
create_point
(
result
,
m_data
+
4
+
(
num
-
1
)
*
POINT_DATA_SIZE
);
return
create_point
(
result
,
m_data
+
4
+
(
num
-
1
)
*
POINT_DATA_SIZE
);
}
}
const
Geometry
::
Class_info
*
Gis_line_string
::
get_class_info
()
const
{
return
&
linestring_class
;
}
/***************************** Polygon *******************************/
/***************************** Polygon *******************************/
...
@@ -570,7 +599,7 @@ bool Gis_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -570,7 +599,7 @@ bool Gis_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
}
bool
Gis_polygon
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
bool
Gis_polygon
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
{
{
uint32
n_linear_rings
;
uint32
n_linear_rings
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -622,7 +651,7 @@ bool Gis_polygon::get_mbr(MBR *mbr, const char **end) const
...
@@ -622,7 +651,7 @@ bool Gis_polygon::get_mbr(MBR *mbr, const char **end) const
}
}
bool
Gis_polygon
::
area
(
double
*
ar
,
const
char
**
end_of_data
)
const
int
Gis_polygon
::
area
(
double
*
ar
,
const
char
**
end_of_data
)
const
{
{
uint32
n_linear_rings
;
uint32
n_linear_rings
;
double
result
=
-
1.0
;
double
result
=
-
1.0
;
...
@@ -671,7 +700,7 @@ bool Gis_polygon::area(double *ar, const char **end_of_data) const
...
@@ -671,7 +700,7 @@ bool Gis_polygon::area(double *ar, const char **end_of_data) const
}
}
bool
Gis_polygon
::
exterior_ring
(
String
*
result
)
int
Gis_polygon
::
exterior_ring
(
String
*
result
)
const
{
{
uint32
n_points
,
length
;
uint32
n_points
,
length
;
const
char
*
data
=
m_data
+
4
;
// skip n_linerings
const
char
*
data
=
m_data
+
4
;
// skip n_linerings
...
@@ -684,15 +713,15 @@ bool Gis_polygon::exterior_ring(String *result)
...
@@ -684,15 +713,15 @@ bool Gis_polygon::exterior_ring(String *result)
if
(
no_data
(
data
,
length
)
||
result
->
reserve
(
1
+
4
+
4
+
length
))
if
(
no_data
(
data
,
length
)
||
result
->
reserve
(
1
+
4
+
4
+
length
))
return
1
;
return
1
;
result
->
q_append
((
char
)
wkb
NDR
);
result
->
q_append
((
char
)
wkb
_ndr
);
result
->
q_append
((
uint32
)
wkb
LineS
tring
);
result
->
q_append
((
uint32
)
wkb
_lines
tring
);
result
->
q_append
(
n_points
);
result
->
q_append
(
n_points
);
result
->
q_append
(
data
,
n_points
*
POINT_DATA_SIZE
);
result
->
q_append
(
data
,
n_points
*
POINT_DATA_SIZE
);
return
0
;
return
0
;
}
}
bool
Gis_polygon
::
num_interior_ring
(
uint32
*
n_int_rings
)
const
int
Gis_polygon
::
num_interior_ring
(
uint32
*
n_int_rings
)
const
{
{
if
(
no_data
(
m_data
,
4
))
if
(
no_data
(
m_data
,
4
))
return
1
;
return
1
;
...
@@ -701,7 +730,7 @@ bool Gis_polygon::num_interior_ring(uint32 *n_int_rings) const
...
@@ -701,7 +730,7 @@ bool Gis_polygon::num_interior_ring(uint32 *n_int_rings) const
}
}
bool
Gis_polygon
::
interior_ring_n
(
uint32
num
,
String
*
result
)
const
int
Gis_polygon
::
interior_ring_n
(
uint32
num
,
String
*
result
)
const
{
{
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
uint32
n_linear_rings
;
uint32
n_linear_rings
;
...
@@ -730,8 +759,8 @@ bool Gis_polygon::interior_ring_n(uint32 num, String *result) const
...
@@ -730,8 +759,8 @@ bool Gis_polygon::interior_ring_n(uint32 num, String *result) const
if
(
no_data
(
data
,
points_size
)
||
result
->
reserve
(
1
+
4
+
4
+
points_size
))
if
(
no_data
(
data
,
points_size
)
||
result
->
reserve
(
1
+
4
+
4
+
points_size
))
return
1
;
return
1
;
result
->
q_append
((
char
)
wkb
NDR
);
result
->
q_append
((
char
)
wkb
_ndr
);
result
->
q_append
((
uint32
)
wkb
LineS
tring
);
result
->
q_append
((
uint32
)
wkb
_lines
tring
);
result
->
q_append
(
n_points
);
result
->
q_append
(
n_points
);
result
->
q_append
(
data
,
points_size
);
result
->
q_append
(
data
,
points_size
);
...
@@ -739,7 +768,7 @@ bool Gis_polygon::interior_ring_n(uint32 num, String *result) const
...
@@ -739,7 +768,7 @@ bool Gis_polygon::interior_ring_n(uint32 num, String *result) const
}
}
bool
Gis_polygon
::
centroid_xy
(
double
*
x
,
double
*
y
)
const
int
Gis_polygon
::
centroid_xy
(
double
*
x
,
double
*
y
)
const
{
{
uint32
n_linear_rings
;
uint32
n_linear_rings
;
double
res_area
,
res_cx
,
res_cy
;
double
res_area
,
res_cx
,
res_cy
;
...
@@ -812,7 +841,7 @@ bool Gis_polygon::centroid_xy(double *x, double *y) const
...
@@ -812,7 +841,7 @@ bool Gis_polygon::centroid_xy(double *x, double *y) const
}
}
bool
Gis_polygon
::
centroid
(
String
*
result
)
int
Gis_polygon
::
centroid
(
String
*
result
)
const
{
{
double
x
,
y
;
double
x
,
y
;
if
(
centroid_xy
(
&
x
,
&
y
))
if
(
centroid_xy
(
&
x
,
&
y
))
...
@@ -820,6 +849,11 @@ bool Gis_polygon::centroid(String *result)
...
@@ -820,6 +849,11 @@ bool Gis_polygon::centroid(String *result)
return
create_point
(
result
,
x
,
y
);
return
create_point
(
result
,
x
,
y
);
}
}
const
Geometry
::
Class_info
*
Gis_polygon
::
get_class_info
()
const
{
return
&
polygon_class
;
}
/***************************** MultiPoint *******************************/
/***************************** MultiPoint *******************************/
...
@@ -845,8 +879,8 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -845,8 +879,8 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
{
if
(
wkb
->
reserve
(
1
+
4
,
512
))
if
(
wkb
->
reserve
(
1
+
4
,
512
))
return
1
;
return
1
;
wkb
->
q_append
((
char
)
wkb
NDR
);
wkb
->
q_append
((
char
)
wkb
_ndr
);
wkb
->
q_append
((
uint32
)
wkb
P
oint
);
wkb
->
q_append
((
uint32
)
wkb
_p
oint
);
if
(
p
.
init_from_wkt
(
trs
,
wkb
))
if
(
p
.
init_from_wkt
(
trs
,
wkb
))
return
1
;
return
1
;
n_points
++
;
n_points
++
;
...
@@ -858,7 +892,7 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -858,7 +892,7 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
}
bool
Gis_multi_point
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
bool
Gis_multi_point
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
{
{
uint32
n_points
;
uint32
n_points
;
if
(
no_data
(
m_data
,
4
))
if
(
no_data
(
m_data
,
4
))
...
@@ -881,14 +915,14 @@ bool Gis_multi_point::get_mbr(MBR *mbr, const char **end) const
...
@@ -881,14 +915,14 @@ bool Gis_multi_point::get_mbr(MBR *mbr, const char **end) const
}
}
bool
Gis_multi_point
::
num_geometries
(
uint32
*
num
)
const
int
Gis_multi_point
::
num_geometries
(
uint32
*
num
)
const
{
{
*
num
=
uint4korr
(
m_data
);
*
num
=
uint4korr
(
m_data
);
return
0
;
return
0
;
}
}
bool
Gis_multi_point
::
geometry_n
(
uint32
num
,
String
*
result
)
const
int
Gis_multi_point
::
geometry_n
(
uint32
num
,
String
*
result
)
const
{
{
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
uint32
n_points
;
uint32
n_points
;
...
@@ -907,10 +941,15 @@ bool Gis_multi_point::geometry_n(uint32 num, String *result) const
...
@@ -907,10 +941,15 @@ bool Gis_multi_point::geometry_n(uint32 num, String *result) const
return
0
;
return
0
;
}
}
const
Geometry
::
Class_info
*
Gis_multi_point
::
get_class_info
()
const
{
return
&
multipoint_class
;
}
/***************************** MultiLineString *******************************/
/***************************** MultiLineString *******************************/
uint32
Gis_multi_line_string
g
::
get_data_size
()
const
uint32
Gis_multi_line_string
::
get_data_size
()
const
{
{
uint32
n_line_strings
;
uint32
n_line_strings
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -931,7 +970,7 @@ uint32 Gis_multi_line_stringg::get_data_size() const
...
@@ -931,7 +970,7 @@ uint32 Gis_multi_line_stringg::get_data_size() const
}
}
bool
Gis_multi_line_string
g
::
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
)
bool
Gis_multi_line_string
::
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
)
{
{
uint32
n_line_strings
=
0
;
uint32
n_line_strings
=
0
;
uint32
ls_pos
=
wkb
->
length
();
uint32
ls_pos
=
wkb
->
length
();
...
@@ -946,8 +985,8 @@ bool Gis_multi_line_stringg::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -946,8 +985,8 @@ bool Gis_multi_line_stringg::init_from_wkt(Gis_read_stream *trs, String *wkb)
if
(
wkb
->
reserve
(
1
+
4
,
512
))
if
(
wkb
->
reserve
(
1
+
4
,
512
))
return
1
;
return
1
;
wkb
->
q_append
((
char
)
wkb
NDR
);
wkb
->
q_append
((
char
)
wkb
_ndr
);
wkb
->
q_append
((
uint32
)
wkb
LineS
tring
);
wkb
->
q_append
((
uint32
)
wkb
_lines
tring
);
if
(
trs
->
check_next_symbol
(
'('
)
||
if
(
trs
->
check_next_symbol
(
'('
)
||
ls
.
init_from_wkt
(
trs
,
wkb
)
||
ls
.
init_from_wkt
(
trs
,
wkb
)
||
...
@@ -962,7 +1001,8 @@ bool Gis_multi_line_stringg::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -962,7 +1001,8 @@ bool Gis_multi_line_stringg::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
}
bool
Gis_multi_line_stringg
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
bool
Gis_multi_line_string
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
{
{
uint32
n_line_strings
;
uint32
n_line_strings
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -993,7 +1033,7 @@ bool Gis_multi_line_stringg::get_data_as_wkt(String *txt, const char **end)
...
@@ -993,7 +1033,7 @@ bool Gis_multi_line_stringg::get_data_as_wkt(String *txt, const char **end)
}
}
bool
Gis_multi_line_string
g
::
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
bool
Gis_multi_line_string
::
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
{
{
uint32
n_line_strings
;
uint32
n_line_strings
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -1014,14 +1054,14 @@ bool Gis_multi_line_stringg::get_mbr(MBR *mbr, const char **end) const
...
@@ -1014,14 +1054,14 @@ bool Gis_multi_line_stringg::get_mbr(MBR *mbr, const char **end) const
}
}
bool
Gis_multi_line_string
g
::
num_geometries
(
uint32
*
num
)
const
int
Gis_multi_line_strin
g
::
num_geometries
(
uint32
*
num
)
const
{
{
*
num
=
uint4korr
(
m_data
);
*
num
=
uint4korr
(
m_data
);
return
0
;
return
0
;
}
}
bool
Gis_multi_line_string
g
::
geometry_n
(
uint32
num
,
String
*
result
)
const
int
Gis_multi_line_strin
g
::
geometry_n
(
uint32
num
,
String
*
result
)
const
{
{
uint32
n_line_strings
,
n_points
,
length
;
uint32
n_line_strings
,
n_points
,
length
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -1050,7 +1090,7 @@ bool Gis_multi_line_stringg::geometry_n(uint32 num, String *result) const
...
@@ -1050,7 +1090,7 @@ bool Gis_multi_line_stringg::geometry_n(uint32 num, String *result) const
}
}
bool
Gis_multi_line_string
g
::
length
(
double
*
len
)
const
int
Gis_multi_line_strin
g
::
length
(
double
*
len
)
const
{
{
uint32
n_line_strings
;
uint32
n_line_strings
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -1080,7 +1120,7 @@ bool Gis_multi_line_stringg::length(double *len) const
...
@@ -1080,7 +1120,7 @@ bool Gis_multi_line_stringg::length(double *len) const
}
}
bool
Gis_multi_line_string
g
::
is_closed
(
int
*
closed
)
const
int
Gis_multi_line_strin
g
::
is_closed
(
int
*
closed
)
const
{
{
uint32
n_line_strings
;
uint32
n_line_strings
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -1109,6 +1149,11 @@ bool Gis_multi_line_stringg::is_closed(int *closed) const
...
@@ -1109,6 +1149,11 @@ bool Gis_multi_line_stringg::is_closed(int *closed) const
return
0
;
return
0
;
}
}
const
Geometry
::
Class_info
*
Gis_multi_line_string
::
get_class_info
()
const
{
return
&
multilinestring_class
;
}
/***************************** MultiPolygon *******************************/
/***************************** MultiPolygon *******************************/
...
@@ -1156,8 +1201,8 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -1156,8 +1201,8 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
{
if
(
wkb
->
reserve
(
1
+
4
,
512
))
if
(
wkb
->
reserve
(
1
+
4
,
512
))
return
1
;
return
1
;
wkb
->
q_append
((
char
)
wkb
NDR
);
wkb
->
q_append
((
char
)
wkb
_ndr
);
wkb
->
q_append
((
uint32
)
wkb
P
olygon
);
wkb
->
q_append
((
uint32
)
wkb
_p
olygon
);
if
(
trs
->
check_next_symbol
(
'('
)
||
if
(
trs
->
check_next_symbol
(
'('
)
||
p
.
init_from_wkt
(
trs
,
wkb
)
||
p
.
init_from_wkt
(
trs
,
wkb
)
||
...
@@ -1172,7 +1217,7 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -1172,7 +1217,7 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
}
bool
Gis_multi_polygon
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
bool
Gis_multi_polygon
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
{
{
uint32
n_polygons
;
uint32
n_polygons
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -1245,14 +1290,14 @@ bool Gis_multi_polygon::get_mbr(MBR *mbr, const char **end) const
...
@@ -1245,14 +1290,14 @@ bool Gis_multi_polygon::get_mbr(MBR *mbr, const char **end) const
}
}
bool
Gis_multi_polygon
::
num_geometries
(
uint32
*
num
)
const
int
Gis_multi_polygon
::
num_geometries
(
uint32
*
num
)
const
{
{
*
num
=
uint4korr
(
m_data
);
*
num
=
uint4korr
(
m_data
);
return
0
;
return
0
;
}
}
bool
Gis_multi_polygon
::
geometry_n
(
uint32
num
,
String
*
result
)
const
int
Gis_multi_polygon
::
geometry_n
(
uint32
num
,
String
*
result
)
const
{
{
uint32
n_polygons
;
uint32
n_polygons
;
const
char
*
data
=
m_data
,
*
start_of_polygon
;
const
char
*
data
=
m_data
,
*
start_of_polygon
;
...
@@ -1291,7 +1336,7 @@ bool Gis_multi_polygon::geometry_n(uint32 num, String *result) const
...
@@ -1291,7 +1336,7 @@ bool Gis_multi_polygon::geometry_n(uint32 num, String *result) const
}
}
bool
Gis_multi_polygon
::
area
(
double
*
ar
,
const
char
**
end_of_data
)
const
int
Gis_multi_polygon
::
area
(
double
*
ar
,
const
char
**
end_of_data
)
const
{
{
uint32
n_polygons
;
uint32
n_polygons
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
...
@@ -1319,7 +1364,7 @@ bool Gis_multi_polygon::area(double *ar, const char **end_of_data) const
...
@@ -1319,7 +1364,7 @@ bool Gis_multi_polygon::area(double *ar, const char **end_of_data) const
}
}
bool
Gis_multi_polygon
::
centroid
(
String
*
result
)
int
Gis_multi_polygon
::
centroid
(
String
*
result
)
const
{
{
uint32
n_polygons
;
uint32
n_polygons
;
bool
first_loop
=
1
;
bool
first_loop
=
1
;
...
@@ -1363,6 +1408,11 @@ bool Gis_multi_polygon::centroid(String *result)
...
@@ -1363,6 +1408,11 @@ bool Gis_multi_polygon::centroid(String *result)
return
create_point
(
result
,
res_cx
,
res_cy
);
return
create_point
(
result
,
res_cx
,
res_cy
);
}
}
const
Geometry
::
Class_info
*
Gis_multi_polygon
::
get_class_info
()
const
{
return
&
multipolygon_class
;
}
/************************* GeometryCollection ****************************/
/************************* GeometryCollection ****************************/
...
@@ -1370,6 +1420,8 @@ uint32 Gis_geometry_collection::get_data_size() const
...
@@ -1370,6 +1420,8 @@ uint32 Gis_geometry_collection::get_data_size() const
{
{
uint32
n_objects
;
uint32
n_objects
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
if
(
no_data
(
data
,
4
))
if
(
no_data
(
data
,
4
))
return
GET_SIZE_ERROR
;
return
GET_SIZE_ERROR
;
...
@@ -1379,17 +1431,16 @@ uint32 Gis_geometry_collection::get_data_size() const
...
@@ -1379,17 +1431,16 @@ uint32 Gis_geometry_collection::get_data_size() const
while
(
n_objects
--
)
while
(
n_objects
--
)
{
{
uint32
wkb_type
,
object_size
;
uint32
wkb_type
,
object_size
;
Geometry
geom
;
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
return
GET_SIZE_ERROR
;
return
GET_SIZE_ERROR
;
wkb_type
=
uint4korr
(
data
+
1
);
wkb_type
=
uint4korr
(
data
+
1
);
data
+=
WKB_HEADER_SIZE
;
data
+=
WKB_HEADER_SIZE
;
if
(
geom
.
init
(
wkb_type
))
if
(
!
(
geom
=
create_by_typeid
(
&
buffer
,
wkb_type
)
))
return
GET_SIZE_ERROR
;
return
GET_SIZE_ERROR
;
geom
.
init_from_wkb
(
data
,
(
uint
)
(
m_data_end
-
data
));
geom
->
init_from_wkb
(
data
,
(
uint
)
(
m_data_end
-
data
));
if
((
object_size
=
geom
.
get_data_size
())
==
GET_SIZE_ERROR
)
if
((
object_size
=
geom
->
get_data_size
())
==
GET_SIZE_ERROR
)
return
GET_SIZE_ERROR
;
return
GET_SIZE_ERROR
;
data
+=
object_size
;
data
+=
object_size
;
}
}
...
@@ -1401,7 +1452,8 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -1401,7 +1452,8 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
{
uint32
n_objects
=
0
;
uint32
n_objects
=
0
;
uint32
no_pos
=
wkb
->
length
();
uint32
no_pos
=
wkb
->
length
();
Geometry
g
;
Geometry_buffer
buffer
;
Geometry
*
g
;
if
(
wkb
->
reserve
(
4
,
512
))
if
(
wkb
->
reserve
(
4
,
512
))
return
1
;
return
1
;
...
@@ -1409,10 +1461,10 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -1409,10 +1461,10 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
for
(;;)
for
(;;)
{
{
if
(
g
.
create_from_wkt
(
trs
,
wkb
))
if
(
!
(
g
=
create_from_wkt
(
&
buffer
,
trs
,
wkb
)
))
return
1
;
return
1
;
if
(
g
.
get_class_info
()
->
m_type_id
==
wkbGeometryC
ollection
)
if
(
g
->
get_class_info
()
->
m_type_id
==
wkb_geometryc
ollection
)
{
{
trs
->
set_error_msg
(
"Unexpected GEOMETRYCOLLECTION"
);
trs
->
set_error_msg
(
"Unexpected GEOMETRYCOLLECTION"
);
return
1
;
return
1
;
...
@@ -1427,10 +1479,12 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
...
@@ -1427,10 +1479,12 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
}
bool
Gis_geometry_collection
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
bool
Gis_geometry_collection
::
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
{
{
uint32
n_objects
;
uint32
n_objects
;
Geometry
geom
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
if
(
no_data
(
data
,
4
))
if
(
no_data
(
data
,
4
))
...
@@ -1447,10 +1501,10 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt, const char **end)
...
@@ -1447,10 +1501,10 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt, const char **end)
wkb_type
=
uint4korr
(
data
+
1
);
wkb_type
=
uint4korr
(
data
+
1
);
data
+=
WKB_HEADER_SIZE
;
data
+=
WKB_HEADER_SIZE
;
if
(
geom
.
init
(
wkb_type
))
if
(
!
(
geom
=
create_by_typeid
(
&
buffer
,
wkb_type
)
))
return
1
;
return
1
;
geom
.
init_from_wkb
(
data
,
(
uint
)
(
m_data_end
-
data
));
geom
->
init_from_wkb
(
data
,
(
uint
)
(
m_data_end
-
data
));
if
(
geom
.
as_wkt
(
txt
,
&
data
))
if
(
geom
->
as_wkt
(
txt
,
&
data
))
return
1
;
return
1
;
if
(
txt
->
append
(
","
,
1
,
512
))
if
(
txt
->
append
(
","
,
1
,
512
))
return
1
;
return
1
;
...
@@ -1465,6 +1519,8 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
...
@@ -1465,6 +1519,8 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
{
{
uint32
n_objects
;
uint32
n_objects
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
if
(
no_data
(
data
,
4
))
if
(
no_data
(
data
,
4
))
return
1
;
return
1
;
...
@@ -1474,17 +1530,16 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
...
@@ -1474,17 +1530,16 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
while
(
n_objects
--
)
while
(
n_objects
--
)
{
{
uint32
wkb_type
;
uint32
wkb_type
;
Geometry
geom
;
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
return
1
;
return
1
;
wkb_type
=
uint4korr
(
data
+
1
);
wkb_type
=
uint4korr
(
data
+
1
);
data
+=
WKB_HEADER_SIZE
;
data
+=
WKB_HEADER_SIZE
;
if
(
geom
.
init
(
wkb_type
))
if
(
!
(
geom
=
create_by_typeid
(
&
buffer
,
wkb_type
)
))
return
1
;
return
1
;
geom
.
init_from_wkb
(
data
,
(
uint32
)
(
m_data_end
-
data
));
geom
->
init_from_wkb
(
data
,
(
uint32
)
(
m_data_end
-
data
));
if
(
geom
.
get_mbr
(
mbr
,
&
data
))
if
(
geom
->
get_mbr
(
mbr
,
&
data
))
return
1
;
return
1
;
}
}
*
end
=
data
;
*
end
=
data
;
...
@@ -1492,7 +1547,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
...
@@ -1492,7 +1547,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
}
}
bool
Gis_geometry_collection
::
num_geometries
(
uint32
*
num
)
const
int
Gis_geometry_collection
::
num_geometries
(
uint32
*
num
)
const
{
{
if
(
no_data
(
m_data
,
4
))
if
(
no_data
(
m_data
,
4
))
return
1
;
return
1
;
...
@@ -1501,10 +1556,12 @@ bool Gis_geometry_collection::num_geometries(uint32 *num) const
...
@@ -1501,10 +1556,12 @@ bool Gis_geometry_collection::num_geometries(uint32 *num) const
}
}
bool
Gis_geometry_collection
::
geometry_n
(
uint32
num
,
String
*
result
)
const
int
Gis_geometry_collection
::
geometry_n
(
uint32
num
,
String
*
result
)
const
{
{
uint32
n_objects
,
wkb_type
,
length
;
uint32
n_objects
,
wkb_type
,
length
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
if
(
no_data
(
data
,
4
))
if
(
no_data
(
data
,
4
))
return
1
;
return
1
;
...
@@ -1515,17 +1572,15 @@ bool Gis_geometry_collection::geometry_n(uint32 num, String *result) const
...
@@ -1515,17 +1572,15 @@ bool Gis_geometry_collection::geometry_n(uint32 num, String *result) const
do
do
{
{
Geometry
geom
;
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
return
1
;
return
1
;
wkb_type
=
uint4korr
(
data
+
1
);
wkb_type
=
uint4korr
(
data
+
1
);
data
+=
WKB_HEADER_SIZE
;
data
+=
WKB_HEADER_SIZE
;
if
(
geom
.
init
(
wkb_type
))
if
(
!
(
geom
=
create_by_typeid
(
&
buffer
,
wkb_type
)
))
return
1
;
return
1
;
geom
.
init_from_wkb
(
data
,
(
uint
)
(
m_data_end
-
data
));
geom
->
init_from_wkb
(
data
,
(
uint
)
(
m_data_end
-
data
));
if
((
length
=
geom
.
get_data_size
())
==
GET_SIZE_ERROR
)
if
((
length
=
geom
->
get_data_size
())
==
GET_SIZE_ERROR
)
return
1
;
return
1
;
data
+=
length
;
data
+=
length
;
}
while
(
--
num
);
}
while
(
--
num
);
...
@@ -1533,7 +1588,7 @@ bool Gis_geometry_collection::geometry_n(uint32 num, String *result) const
...
@@ -1533,7 +1588,7 @@ bool Gis_geometry_collection::geometry_n(uint32 num, String *result) const
/* Copy found object to result */
/* Copy found object to result */
if
(
result
->
reserve
(
1
+
4
+
length
))
if
(
result
->
reserve
(
1
+
4
+
length
))
return
1
;
return
1
;
result
->
q_append
((
char
)
wkb
NDR
);
result
->
q_append
((
char
)
wkb
_ndr
);
result
->
q_append
((
uint32
)
wkb_type
);
result
->
q_append
((
uint32
)
wkb_type
);
result
->
q_append
(
data
-
length
,
length
);
// data-length = start_of_data
result
->
q_append
(
data
-
length
,
length
);
// data-length = start_of_data
return
0
;
return
0
;
...
@@ -1557,6 +1612,8 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
...
@@ -1557,6 +1612,8 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
{
{
uint32
n_objects
;
uint32
n_objects
;
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
Geometry_buffer
buffer
;
Geometry
*
geom
;
if
(
no_data
(
data
,
4
))
if
(
no_data
(
data
,
4
))
return
1
;
return
1
;
...
@@ -1568,21 +1625,20 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
...
@@ -1568,21 +1625,20 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
{
{
uint32
wkb_type
,
length
,
dim
;
uint32
wkb_type
,
length
,
dim
;
const
char
*
end_data
;
const
char
*
end_data
;
Geometry
geom
;
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
if
(
no_data
(
data
,
WKB_HEADER_SIZE
))
return
1
;
return
1
;
wkb_type
=
uint4korr
(
data
+
1
);
wkb_type
=
uint4korr
(
data
+
1
);
data
+=
WKB_HEADER_SIZE
;
data
+=
WKB_HEADER_SIZE
;
if
(
geom
.
init
(
wkb_type
))
if
(
!
(
geom
=
create_by_typeid
(
&
buffer
,
wkb_type
)
))
return
1
;
return
1
;
geom
.
init_from_wkb
(
data
,
(
uint32
)
(
m_data_end
-
data
));
geom
->
init_from_wkb
(
data
,
(
uint32
)
(
m_data_end
-
data
));
if
(
geom
.
dimension
(
&
dim
,
&
end_data
))
if
(
geom
->
dimension
(
&
dim
,
&
end_data
))
return
1
;
return
1
;
set_if_bigger
(
*
res_dim
,
dim
);
set_if_bigger
(
*
res_dim
,
dim
);
if
(
end_data
)
// Complex object
if
(
end_data
)
// Complex object
data
=
end_data
;
data
=
end_data
;
else
if
((
length
=
geom
.
get_data_size
())
==
GET_SIZE_ERROR
)
else
if
((
length
=
geom
->
get_data_size
())
==
GET_SIZE_ERROR
)
return
1
;
return
1
;
else
else
data
+=
length
;
data
+=
length
;
...
@@ -1590,3 +1646,9 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
...
@@ -1590,3 +1646,9 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
*
end
=
data
;
*
end
=
data
;
return
0
;
return
0
;
}
}
const
Geometry
::
Class_info
*
Gis_geometry_collection
::
get_class_info
()
const
{
return
&
geometrycollection_class
;
}
sql/spatial.h
View file @
6aa1cc4a
...
@@ -152,142 +152,80 @@ struct MBR
...
@@ -152,142 +152,80 @@ struct MBR
/***************************** Geometry *******************************/
/***************************** Geometry *******************************/
class
Geometry
;
struct
Geometry_buffer
;
typedef
bool
(
Geometry
::*
GF_InitFromText
)(
Gis_read_stream
*
,
String
*
);
typedef
bool
(
Geometry
::*
GF_GetDataAsText
)(
String
*
,
const
char
**
);
typedef
uint32
(
Geometry
::*
GF_GetDataSize
)()
const
;
typedef
bool
(
Geometry
::*
GF_GetMBR
)(
MBR
*
,
const
char
**
end
)
const
;
typedef
bool
(
Geometry
::*
GF_GetD
)(
double
*
)
const
;
typedef
bool
(
Geometry
::*
GF_GetD_AND_END
)(
double
*
,
const
char
**
)
const
;
typedef
bool
(
Geometry
::*
GF_GetI
)(
int
*
)
const
;
typedef
bool
(
Geometry
::*
GF_GetUI
)(
uint32
*
)
const
;
typedef
bool
(
Geometry
::*
GF_GetUI_AND_END
)(
uint32
*
,
const
char
**
)
const
;
typedef
bool
(
Geometry
::*
GF_GetWS
)(
String
*
);
typedef
bool
(
Geometry
::*
GF_GetUIWS
)(
uint32
,
String
*
)
const
;
#define GEOM_METHOD_PRESENT(geom_obj, method)\
(geom_obj.m_vmt->method != &Geometry::method)
class
Geometry
class
Geometry
{
{
public:
public:
static
void
*
operator
new
(
unsigned
size_t
,
void
*
buffer
)
{
return
buffer
;
}
enum
wkbType
enum
wkbType
{
{
wkb
P
oint
=
1
,
wkb
_p
oint
=
1
,
wkb
LineS
tring
=
2
,
wkb
_lines
tring
=
2
,
wkb
P
olygon
=
3
,
wkb
_p
olygon
=
3
,
wkb
MultiP
oint
=
4
,
wkb
_multip
oint
=
4
,
wkb
MultiLineS
tring
=
5
,
wkb
_multilines
tring
=
5
,
wkb
MultiP
olygon
=
6
,
wkb
_multip
olygon
=
6
,
wkb
GeometryC
ollection
=
7
,
wkb
_geometryc
ollection
=
7
,
wkb_end
=
8
wkb_end
=
7
};
};
enum
wkbByteOrder
enum
wkbByteOrder
{
{
wkb
XDR
=
0
,
/* Big Endian */
wkb
_xdr
=
0
,
/* Big Endian */
wkb
NDR
=
1
/* Little Endian */
wkb
_ndr
=
1
/* Little Endian */
};
};
class
Gis_c
lass_info
class
C
lass_info
{
{
public:
public:
GF_InitFromText
init_from_wkt
;
LEX_STRING_WITH_INIT
m_name
;
GF_GetDataAsText
get_data_as_wkt
;
GF_GetDataSize
get_data_size
;
GF_GetMBR
get_mbr
;
GF_GetD
get_x
;
GF_GetD
get_y
;
GF_GetD
length
;
GF_GetD_AND_END
area
;
GF_GetI
is_closed
;
GF_GetUI
num_interior_ring
;
GF_GetUI
num_points
;
GF_GetUI
num_geometries
;
GF_GetUI_AND_END
dimension
;
GF_GetWS
start_point
;
GF_GetWS
end_point
;
GF_GetWS
exterior_ring
;
GF_GetWS
centroid
;
GF_GetUIWS
point_n
;
GF_GetUIWS
interior_ring_n
;
GF_GetUIWS
geometry_n
;
LEX_STRING
m_name
;
int
m_type_id
;
int
m_type_id
;
Gis_class_info
*
m_next_rt
;
void
(
*
m_create_func
)(
void
*
);
Class_info
(
const
char
*
name
,
int
type_id
,
void
(
*
create_func
)(
void
*
));
};
};
Gis_class_info
*
m_vmt
;
const
Gis_class_info
*
get_class_info
()
const
{
return
m_vmt
;
}
uint32
get_data_size
()
const
{
return
(
this
->*
m_vmt
->
get_data_size
)();
}
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
)
virtual
const
Class_info
*
get_class_info
()
const
=
0
;
{
return
(
this
->*
m_vmt
->
init_from_wkt
)(
trs
,
wkb
);
}
virtual
uint32
get_data_size
()
const
=
0
;
virtual
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
)
=
0
;
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
virtual
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
=
0
;
{
return
(
this
->*
m_vmt
->
get_data_as_wkt
)(
txt
,
end
);
}
virtual
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
=
0
;
virtual
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
=
0
;
int
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
virtual
int
get_x
(
double
*
x
)
const
{
return
-
1
;
}
{
return
(
this
->*
m_vmt
->
get_mbr
)(
mbr
,
end
);
}
virtual
int
get_y
(
double
*
y
)
const
{
return
-
1
;
}
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
virtual
int
length
(
double
*
len
)
const
{
return
-
1
;
}
{
virtual
int
area
(
double
*
ar
,
const
char
**
end
)
const
{
return
-
1
;}
return
(
this
->*
m_vmt
->
dimension
)(
dim
,
end
);
virtual
int
is_closed
(
int
*
closed
)
const
{
return
-
1
;
}
}
virtual
int
num_interior_ring
(
uint32
*
n_int_rings
)
const
{
return
-
1
;
}
virtual
int
num_points
(
uint32
*
n_points
)
const
{
return
-
1
;
}
bool
get_x
(
double
*
x
)
const
{
return
(
this
->*
m_vmt
->
get_x
)(
x
);
}
virtual
int
num_geometries
(
uint32
*
num
)
const
{
return
-
1
;
}
bool
get_y
(
double
*
y
)
const
{
return
(
this
->*
m_vmt
->
get_y
)(
y
);
}
virtual
int
start_point
(
String
*
point
)
const
{
return
-
1
;
}
bool
length
(
double
*
len
)
const
{
return
(
this
->*
m_vmt
->
length
)(
len
);
}
virtual
int
end_point
(
String
*
point
)
const
{
return
-
1
;
}
bool
area
(
double
*
ar
,
const
char
**
end
)
const
virtual
int
exterior_ring
(
String
*
ring
)
const
{
return
-
1
;
}
{
virtual
int
centroid
(
String
*
point
)
const
{
return
-
1
;
}
return
(
this
->*
m_vmt
->
area
)(
ar
,
end
);
virtual
int
point_n
(
uint32
num
,
String
*
result
)
const
{
return
-
1
;
}
}
virtual
int
interior_ring_n
(
uint32
num
,
String
*
result
)
const
{
return
-
1
;
}
virtual
int
geometry_n
(
uint32
num
,
String
*
result
)
const
{
return
-
1
;
}
bool
is_closed
(
int
*
closed
)
const
{
return
(
this
->*
m_vmt
->
is_closed
)(
closed
);
}
bool
num_interior_ring
(
uint32
*
n_int_rings
)
const
{
return
(
this
->*
m_vmt
->
num_interior_ring
)(
n_int_rings
);
}
bool
num_points
(
uint32
*
n_points
)
const
{
return
(
this
->*
m_vmt
->
num_points
)(
n_points
);
}
bool
num_geometries
(
uint32
*
num
)
const
{
return
(
this
->*
m_vmt
->
num_geometries
)(
num
);
}
bool
start_point
(
String
*
point
)
{
return
(
this
->*
m_vmt
->
start_point
)(
point
);
}
bool
end_point
(
String
*
point
)
{
return
(
this
->*
m_vmt
->
end_point
)(
point
);
}
bool
exterior_ring
(
String
*
ring
)
{
return
(
this
->*
m_vmt
->
exterior_ring
)(
ring
);
}
bool
centroid
(
String
*
point
)
{
return
(
this
->*
m_vmt
->
centroid
)(
point
);
}
bool
point_n
(
uint32
num
,
String
*
result
)
const
{
return
(
this
->*
m_vmt
->
point_n
)(
num
,
result
);
}
bool
interior_ring_n
(
uint32
num
,
String
*
result
)
const
{
return
(
this
->*
m_vmt
->
interior_ring_n
)(
num
,
result
);
}
bool
geometry_n
(
uint32
num
,
String
*
result
)
const
{
return
(
this
->*
m_vmt
->
geometry_n
)(
num
,
result
);
}
public:
public:
int
create_from_wkb
(
const
char
*
data
,
uint32
data_len
);
static
Geometry
*
Geometry
::
create_by_typeid
(
Geometry_buffer
*
buffer
,
int
create_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkt
,
bool
init_stream
=
1
);
int
type_id
)
int
init
(
int
type_id
)
{
{
Class_info
*
ci
;
m_vmt
=
find_class
(
type_id
);
if
(
!
(
ci
=
find_class
((
int
)
type_id
)))
return
!
m_vmt
;
return
NULL
;
}
(
*
ci
->
m_create_func
)((
void
*
)
buffer
);
int
new_geometry
(
const
char
*
name
,
uint32
len
)
return
(
Geometry
*
)
buffer
;
{
m_vmt
=
find_class
(
name
,
len
);
return
!
m_vmt
;
}
}
static
Geometry
*
create_from_wkb
(
Geometry_buffer
*
buffer
,
const
char
*
data
,
uint32
data_len
);
static
Geometry
*
create_from_wkt
(
Geometry_buffer
*
buffer
,
Gis_read_stream
*
trs
,
String
*
wkt
,
bool
init_stream
=
1
);
int
as_wkt
(
String
*
wkt
,
const
char
**
end
)
int
as_wkt
(
String
*
wkt
,
const
char
**
end
)
{
{
uint32
len
=
get_class_info
()
->
m_name
.
length
;
uint32
len
=
get_class_info
()
->
m_name
.
length
;
...
@@ -313,14 +251,19 @@ public:
...
@@ -313,14 +251,19 @@ public:
}
}
bool
envelope
(
String
*
result
)
const
;
bool
envelope
(
String
*
result
)
const
;
static
Geometry
::
Class_info
*
ci_collection
[
Geometry
::
wkb_end
];
protected:
protected:
static
Gis_class_info
*
find_class
(
int
type_id
);
static
Class_info
*
find_class
(
int
type_id
)
static
Gis_class_info
*
find_class
(
const
char
*
name
,
uint32
len
);
{
return
((
type_id
<
wkb_point
)
||
(
type_id
>
wkb_end
))
?
NULL
:
ci_collection
[
type_id
];
}
static
Class_info
*
find_class
(
const
char
*
name
,
uint32
len
);
const
char
*
append_points
(
String
*
txt
,
uint32
n_points
,
const
char
*
append_points
(
String
*
txt
,
uint32
n_points
,
const
char
*
data
,
uint32
offset
);
const
char
*
data
,
uint32
offset
)
const
;
bool
create_point
(
String
*
result
,
const
char
*
data
);
bool
create_point
(
String
*
result
,
const
char
*
data
)
const
;
bool
create_point
(
String
*
result
,
double
x
,
double
y
);
bool
create_point
(
String
*
result
,
double
x
,
double
y
)
const
;
const
char
*
get_mbr_for_points
(
MBR
*
mbr
,
const
char
*
data
,
uint
offset
)
const
char
*
get_mbr_for_points
(
MBR
*
mbr
,
const
char
*
data
,
uint
offset
)
const
;
const
;
...
@@ -340,10 +283,10 @@ class Gis_point: public Geometry
...
@@ -340,10 +283,10 @@ class Gis_point: public Geometry
public:
public:
uint32
get_data_size
()
const
;
uint32
get_data_size
()
const
;
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
;
int
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_xy
(
double
*
x
,
double
*
y
)
const
int
get_xy
(
double
*
x
,
double
*
y
)
const
{
{
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
if
(
no_data
(
data
,
SIZEOF_STORED_DOUBLE
*
2
))
if
(
no_data
(
data
,
SIZEOF_STORED_DOUBLE
*
2
))
...
@@ -353,7 +296,7 @@ public:
...
@@ -353,7 +296,7 @@ public:
return
0
;
return
0
;
}
}
bool
get_x
(
double
*
x
)
const
int
get_x
(
double
*
x
)
const
{
{
if
(
no_data
(
m_data
,
SIZEOF_STORED_DOUBLE
))
if
(
no_data
(
m_data
,
SIZEOF_STORED_DOUBLE
))
return
1
;
return
1
;
...
@@ -361,7 +304,7 @@ public:
...
@@ -361,7 +304,7 @@ public:
return
0
;
return
0
;
}
}
bool
get_y
(
double
*
y
)
const
int
get_y
(
double
*
y
)
const
{
{
const
char
*
data
=
m_data
;
const
char
*
data
=
m_data
;
if
(
no_data
(
data
,
SIZEOF_STORED_DOUBLE
*
2
))
return
1
;
if
(
no_data
(
data
,
SIZEOF_STORED_DOUBLE
*
2
))
return
1
;
...
@@ -375,6 +318,7 @@ public:
...
@@ -375,6 +318,7 @@ public:
*
end
=
0
;
/* No default end */
*
end
=
0
;
/* No default end */
return
0
;
return
0
;
}
}
const
Class_info
*
get_class_info
()
const
;
};
};
...
@@ -385,20 +329,21 @@ class Gis_line_string: public Geometry
...
@@ -385,20 +329,21 @@ class Gis_line_string: public Geometry
public:
public:
uint32
get_data_size
()
const
;
uint32
get_data_size
()
const
;
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
length
(
double
*
len
)
const
;
int
length
(
double
*
len
)
const
;
bool
is_closed
(
int
*
closed
)
const
;
int
is_closed
(
int
*
closed
)
const
;
bool
num_points
(
uint32
*
n_points
)
const
;
int
num_points
(
uint32
*
n_points
)
const
;
bool
start_point
(
String
*
point
)
;
int
start_point
(
String
*
point
)
const
;
bool
end_point
(
String
*
point
)
;
int
end_point
(
String
*
point
)
const
;
bool
point_n
(
uint32
n
,
String
*
result
)
;
int
point_n
(
uint32
n
,
String
*
result
)
const
;
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
{
{
*
dim
=
1
;
*
dim
=
1
;
*
end
=
0
;
/* No default end */
*
end
=
0
;
/* No default end */
return
0
;
return
0
;
}
}
const
Class_info
*
get_class_info
()
const
;
};
};
...
@@ -409,20 +354,21 @@ class Gis_polygon: public Geometry
...
@@ -409,20 +354,21 @@ class Gis_polygon: public Geometry
public:
public:
uint32
get_data_size
()
const
;
uint32
get_data_size
()
const
;
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
area
(
double
*
ar
,
const
char
**
end
)
const
;
int
area
(
double
*
ar
,
const
char
**
end
)
const
;
bool
exterior_ring
(
String
*
result
)
;
int
exterior_ring
(
String
*
result
)
const
;
bool
num_interior_ring
(
uint32
*
n_int_rings
)
const
;
int
num_interior_ring
(
uint32
*
n_int_rings
)
const
;
bool
interior_ring_n
(
uint32
num
,
String
*
result
)
const
;
int
interior_ring_n
(
uint32
num
,
String
*
result
)
const
;
bool
centroid_xy
(
double
*
x
,
double
*
y
)
const
;
int
centroid_xy
(
double
*
x
,
double
*
y
)
const
;
bool
centroid
(
String
*
result
)
;
int
centroid
(
String
*
result
)
const
;
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
{
{
*
dim
=
2
;
*
dim
=
2
;
*
end
=
0
;
/* No default end */
*
end
=
0
;
/* No default end */
return
0
;
return
0
;
}
}
const
Class_info
*
get_class_info
()
const
;
};
};
...
@@ -433,38 +379,40 @@ class Gis_multi_point: public Geometry
...
@@ -433,38 +379,40 @@ class Gis_multi_point: public Geometry
public:
public:
uint32
get_data_size
()
const
;
uint32
get_data_size
()
const
;
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
num_geometries
(
uint32
*
num
)
const
;
int
num_geometries
(
uint32
*
num
)
const
;
bool
geometry_n
(
uint32
num
,
String
*
result
)
const
;
int
geometry_n
(
uint32
num
,
String
*
result
)
const
;
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
{
{
*
dim
=
0
;
*
dim
=
0
;
*
end
=
0
;
/* No default end */
*
end
=
0
;
/* No default end */
return
0
;
return
0
;
}
}
const
Class_info
*
get_class_info
()
const
;
};
};
/***************************** MultiLineString *******************************/
/***************************** MultiLineString *******************************/
class
Gis_multi_line_string
g
:
public
Geometry
class
Gis_multi_line_string
:
public
Geometry
{
{
public:
public:
uint32
get_data_size
()
const
;
uint32
get_data_size
()
const
;
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
num_geometries
(
uint32
*
num
)
const
;
int
num_geometries
(
uint32
*
num
)
const
;
bool
geometry_n
(
uint32
num
,
String
*
result
)
const
;
int
geometry_n
(
uint32
num
,
String
*
result
)
const
;
bool
length
(
double
*
len
)
const
;
int
length
(
double
*
len
)
const
;
bool
is_closed
(
int
*
closed
)
const
;
int
is_closed
(
int
*
closed
)
const
;
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
{
{
*
dim
=
1
;
*
dim
=
1
;
*
end
=
0
;
/* No default end */
*
end
=
0
;
/* No default end */
return
0
;
return
0
;
}
}
const
Class_info
*
get_class_info
()
const
;
};
};
...
@@ -475,19 +423,19 @@ class Gis_multi_polygon: public Geometry
...
@@ -475,19 +423,19 @@ class Gis_multi_polygon: public Geometry
public:
public:
uint32
get_data_size
()
const
;
uint32
get_data_size
()
const
;
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
num_geometries
(
uint32
*
num
)
const
;
int
num_geometries
(
uint32
*
num
)
const
;
bool
geometry_n
(
uint32
num
,
String
*
result
)
const
;
int
geometry_n
(
uint32
num
,
String
*
result
)
const
;
bool
area
(
double
*
ar
,
const
char
**
end
)
const
;
int
area
(
double
*
ar
,
const
char
**
end
)
const
;
bool
centroid
(
String
*
result
)
;
int
centroid
(
String
*
result
)
const
;
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
{
{
*
dim
=
2
;
*
dim
=
2
;
*
end
=
0
;
/* No default end */
*
end
=
0
;
/* No default end */
return
0
;
return
0
;
}
}
const
Class_info
*
get_class_info
()
const
;
};
};
...
@@ -498,11 +446,18 @@ class Gis_geometry_collection: public Geometry
...
@@ -498,11 +446,18 @@ class Gis_geometry_collection: public Geometry
public:
public:
uint32
get_data_size
()
const
;
uint32
get_data_size
()
const
;
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
init_from_wkt
(
Gis_read_stream
*
trs
,
String
*
wkb
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
);
bool
get_data_as_wkt
(
String
*
txt
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
get_mbr
(
MBR
*
mbr
,
const
char
**
end
)
const
;
bool
num_geometries
(
uint32
*
num
)
const
;
int
num_geometries
(
uint32
*
num
)
const
;
bool
geometry_n
(
uint32
num
,
String
*
result
)
const
;
int
geometry_n
(
uint32
num
,
String
*
result
)
const
;
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
;
bool
dimension
(
uint32
*
dim
,
const
char
**
end
)
const
;
const
Class_info
*
get_class_info
()
const
;
};
const
int
geometry_buffer_size
=
sizeof
(
Gis_point
);
struct
Geometry_buffer
{
void
*
arr
[(
geometry_buffer_size
-
1
)
/
sizeof
(
void
*
)
+
1
];
};
};
#endif
#endif
sql/sql_yacc.yy
View file @
6aa1cc4a
...
@@ -2941,14 +2941,14 @@ geometry_function:
...
@@ -2941,14 +2941,14 @@ geometry_function:
{ $$= GEOM_NEW(Item_func_geometry_from_wkb($3, $5)); }
{ $$= GEOM_NEW(Item_func_geometry_from_wkb($3, $5)); }
| GEOMETRYCOLLECTION '(' expr_list ')'
| GEOMETRYCOLLECTION '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkb
GeometryC
ollection,
Geometry::wkb
_geometryc
ollection,
Geometry::wkb
P
oint)); }
Geometry::wkb
_p
oint)); }
| LINESTRING '(' expr_list ')'
| LINESTRING '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkb
LineString, Geometry::wkbP
oint)); }
Geometry::wkb
_linestring, Geometry::wkb_p
oint)); }
| MULTILINESTRING '(' expr_list ')'
| MULTILINESTRING '(' expr_list ')'
{ $$= GEOM_NEW( Item_func_spatial_collection(* $3,
{ $$= GEOM_NEW( Item_func_spatial_collection(* $3,
Geometry::wkb
MultiLineString, Geometry::wkbLineS
tring)); }
Geometry::wkb
_multilinestring, Geometry::wkb_lines
tring)); }
| MLINEFROMTEXT '(' expr ')'
| MLINEFROMTEXT '(' expr ')'
{ $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
{ $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
| MLINEFROMTEXT '(' expr ',' expr ')'
| MLINEFROMTEXT '(' expr ',' expr ')'
...
@@ -2963,10 +2963,10 @@ geometry_function:
...
@@ -2963,10 +2963,10 @@ geometry_function:
{ $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
{ $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
| MULTIPOINT '(' expr_list ')'
| MULTIPOINT '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkb
MultiPoint, Geometry::wkbP
oint)); }
Geometry::wkb
_multipoint, Geometry::wkb_p
oint)); }
| MULTIPOLYGON '(' expr_list ')'
| MULTIPOLYGON '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkb
MultiPolygon, Geometry::wkbP
olygon)); }
Geometry::wkb
_multipolygon, Geometry::wkb_p
olygon)); }
| POINT_SYM '(' expr ',' expr ')'
| POINT_SYM '(' expr ',' expr ')'
{ $$= GEOM_NEW(Item_func_point($3,$5)); }
{ $$= GEOM_NEW(Item_func_point($3,$5)); }
| POINTFROMTEXT '(' expr ')'
| POINTFROMTEXT '(' expr ')'
...
@@ -2979,7 +2979,7 @@ geometry_function:
...
@@ -2979,7 +2979,7 @@ geometry_function:
{ $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
{ $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
| POLYGON '(' expr_list ')'
| POLYGON '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkb
Polygon, Geometry::wkbLineS
tring)); }
Geometry::wkb
_polygon, Geometry::wkb_lines
tring)); }
| GEOMCOLLFROMTEXT '(' expr ')'
| GEOMCOLLFROMTEXT '(' expr ')'
{ $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
{ $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
| GEOMCOLLFROMTEXT '(' expr ',' expr ')'
| GEOMCOLLFROMTEXT '(' expr ',' expr ')'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment