Commit d0d6284c authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-4045 Missing OGC Spatial functions.

   Missing GIS functions added:
        IsRing()
        PointOnSurface
        PointOnSurface
        Relate
        Distance
        Intersection
        ConvexHull
   Other old OpenGis standard inconsistencies fixed.
parent 7b55b67d
...@@ -1326,6 +1326,18 @@ WHERE name = 'Route 5' ...@@ -1326,6 +1326,18 @@ WHERE name = 'Route 5'
AND aliases = 'Main Street'; AND aliases = 'Main Street';
IsEmpty(centerline) IsEmpty(centerline)
0 0
# Conformance Item T12
SELECT IsSimple(shore)
FROM lakes
WHERE name = 'Blue Lake';
IsSimple(shore)
1
# Conformance Item T13
SELECT AsText(ST_Boundary(boundary))
FROM named_places
WHERE name = 'Goose Island';
AsText(ST_Boundary(boundary))
LINESTRING(67 13,67 18,59 18,59 13,67 13)
# Conformance Item T14 # Conformance Item T14
SELECT AsText(Envelope(boundary)) SELECT AsText(Envelope(boundary))
FROM named_places FROM named_places
...@@ -1356,6 +1368,17 @@ FROM road_segments ...@@ -1356,6 +1368,17 @@ FROM road_segments
WHERE fid = 102; WHERE fid = 102;
AsText(EndPoint(centerline)) AsText(EndPoint(centerline))
POINT(44 31) POINT(44 31)
SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
FROM named_places
WHERE name = 'Goose Island';
IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
1
# Conformance Item T20
SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
FROM named_places
WHERE name = 'Goose Island';
IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
0
# Conformance Item T21 # Conformance Item T21
SELECT GLength(centerline) SELECT GLength(centerline)
FROM road_segments FROM road_segments
...@@ -1380,6 +1403,11 @@ FROM named_places ...@@ -1380,6 +1403,11 @@ FROM named_places
WHERE name = 'Goose Island'; WHERE name = 'Goose Island';
AsText(Centroid(boundary)) AsText(Centroid(boundary))
POINT(63 15.5) POINT(63 15.5)
SELECT ST_Contains(boundary, PointOnSurface(boundary))
FROM named_places
WHERE name = 'Goose Island';
ST_Contains(boundary, PointOnSurface(boundary))
1
# Conformance Item T26 # Conformance Item T26
SELECT Area(boundary) SELECT Area(boundary)
FROM named_places FROM named_places
...@@ -1434,6 +1462,12 @@ FROM ponds ...@@ -1434,6 +1462,12 @@ FROM ponds
WHERE fid = 120; WHERE fid = 120;
AsText(Centroid(shores)) AsText(Centroid(shores))
POINT(25 42) POINT(25 42)
# Conformance Item T35
SELECT Contains(shores, PointOnSurface(shores))
FROM ponds
WHERE fid = 120;
Contains(shores, PointOnSurface(shores))
1
# Conformance Item T36 # Conformance Item T36
SELECT Area(shores) SELECT Area(shores)
FROM ponds FROM ponds
...@@ -1462,6 +1496,20 @@ WHERE streams.name = 'Cam Stream' ...@@ -1462,6 +1496,20 @@ WHERE streams.name = 'Cam Stream'
AND lakes.name = 'Blue Lake'; AND lakes.name = 'Blue Lake';
ST_Touches(centerline, shore) ST_Touches(centerline, shore)
1 1
# Conformance Item T40
SELECT ST_Within(footprint, boundary)
FROM named_places, buildings
WHERE named_places.name = 'Ashton'
AND buildings.address = '215 Main Street';
ST_Within(footprint, boundary)
1
# Conformance Item T41
SELECT ST_Overlaps(forests.boundary, named_places.boundary)
FROM forests, named_places
WHERE forests.name = 'Green Forest'
AND named_places.name = 'Ashton';
ST_Overlaps(forests.boundary, named_places.boundary)
1
# Conformance Item T42 # Conformance Item T42
SELECT Crosses(road_segments.centerline, divided_routes.centerlines) SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
FROM road_segments, divided_routes FROM road_segments, divided_routes
...@@ -1483,6 +1531,13 @@ WHERE forests.name = 'Green Forest' ...@@ -1483,6 +1531,13 @@ WHERE forests.name = 'Green Forest'
AND named_places.name = 'Ashton'; AND named_places.name = 'Ashton';
ST_Contains(forests.boundary, named_places.boundary) ST_Contains(forests.boundary, named_places.boundary)
0 0
# Conformance Item T45
SELECT ST_Relate(forests.boundary, named_places.boundary, 'TTTTTTTTT')
FROM forests, named_places
WHERE forests.name = 'Green Forest'
AND named_places.name = 'Ashton';
ST_Relate(forests.boundary, named_places.boundary, 'TTTTTTTTT')
1
# Conformance Item T46 # Conformance Item T46
SELECT ST_Distance(position, boundary) SELECT ST_Distance(position, boundary)
FROM bridges, named_places FROM bridges, named_places
...@@ -1490,6 +1545,13 @@ WHERE bridges.name = 'Cam Bridge' ...@@ -1490,6 +1545,13 @@ WHERE bridges.name = 'Cam Bridge'
AND named_places.name = 'Ashton'; AND named_places.name = 'Ashton';
ST_Distance(position, boundary) ST_Distance(position, boundary)
12 12
# Conformance Item T47
SELECT AsText(ST_Intersection(centerline, shore))
FROM streams, lakes
WHERE streams.name = 'Cam Stream'
AND lakes.name = 'Blue Lake';
AsText(ST_Intersection(centerline, shore))
POINT(52 18)
# Conformance Item T48 # Conformance Item T48
SELECT AsText(ST_Difference(named_places.boundary, forests.boundary)) SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
FROM named_places, forests FROM named_places, forests
...@@ -1516,6 +1578,12 @@ FROM buildings, bridges ...@@ -1516,6 +1578,12 @@ FROM buildings, bridges
WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1; WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
count(*) count(*)
1 1
# Conformance Item T52
SELECT AsText(ConvexHull(shore))
FROM lakes
WHERE lakes.name = 'Blue Lake';
AsText(ConvexHull(shore))
POLYGON((48 6,52 18,66 23,73 9,48 6))
DROP DATABASE gis_ogs; DROP DATABASE gis_ogs;
USE test; USE test;
# #
......
...@@ -1119,33 +1119,27 @@ FROM named_places ...@@ -1119,33 +1119,27 @@ FROM named_places
WHERE name = 'Goose Island'; WHERE name = 'Goose Island';
--echo # Conformance Item T10 --echo # Conformance Item T10
# TODO: ST_SRID() alias
SELECT SRID(boundary) SELECT SRID(boundary)
FROM named_places FROM named_places
WHERE name = 'Goose Island'; WHERE name = 'Goose Island';
--echo # Conformance Item T11 --echo # Conformance Item T11
# TODO: ST_IsEmpty() alias
SELECT IsEmpty(centerline) SELECT IsEmpty(centerline)
FROM road_segments FROM road_segments
WHERE name = 'Route 5' WHERE name = 'Route 5'
AND aliases = 'Main Street'; AND aliases = 'Main Street';
# FIXME: get wrong result:0, expected 1. --echo # Conformance Item T12
#--echo # Conformance Item T12 SELECT IsSimple(shore)
# TODO: ST_IsSimple() alias FROM lakes
#SELECT IsSimple(shore) WHERE name = 'Blue Lake';
#FROM lakes
#WHERE name = 'Blue Lake';
# TODO: WL#2377 --echo # Conformance Item T13
#--echo # Conformance Item T13 SELECT AsText(ST_Boundary(boundary))
#SELECT AsText(Boundary((boundary),101) FROM named_places
#FROM named_places WHERE name = 'Goose Island';
#WHERE name = 'Goose Island';
--echo # Conformance Item T14 --echo # Conformance Item T14
# TODO: ST_Envelope( ) alias
# FIXME: we get anticlockwise, GIS suggests clockwise # FIXME: we get anticlockwise, GIS suggests clockwise
SELECT AsText(Envelope(boundary)) SELECT AsText(Envelope(boundary))
FROM named_places FROM named_places
...@@ -1170,122 +1164,100 @@ FROM road_segments ...@@ -1170,122 +1164,100 @@ FROM road_segments
WHERE fid = 102; WHERE fid = 102;
--echo # Conformance Item T18 --echo # Conformance Item T18
# TODO: ST_EndPoint
SELECT AsText(EndPoint(centerline)) SELECT AsText(EndPoint(centerline))
FROM road_segments FROM road_segments
WHERE fid = 102; WHERE fid = 102;
# TODO: WL#2377 SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
#--echo # Conformance Item T19 FROM named_places
# TODO: ST_LineFromWKB() alias WHERE name = 'Goose Island';
#SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
#FROM named_places
#WHERE name = 'Goose Island';
# TODO: WL#2377 --echo # Conformance Item T20
#--echo # Conformance Item T20 SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
#SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) FROM named_places
#FROM named_places WHERE name = 'Goose Island';
#WHERE name = 'Goose Island';
--echo # Conformance Item T21 --echo # Conformance Item T21
# TODO: ST_Length() alias
SELECT GLength(centerline) SELECT GLength(centerline)
FROM road_segments FROM road_segments
WHERE fid = 106; WHERE fid = 106;
--echo # Conformance Item T22 --echo # Conformance Item T22
# TODO: ST_NumPoints() alias
SELECT NumPoints(centerline) SELECT NumPoints(centerline)
FROM road_segments FROM road_segments
WHERE fid = 102; WHERE fid = 102;
--echo # Conformance Item T23 --echo # Conformance Item T23
# TODO: ST_PointN() alias
SELECT AsText(PointN(centerline, 1)) SELECT AsText(PointN(centerline, 1))
FROM road_segments FROM road_segments
WHERE fid = 102; WHERE fid = 102;
--echo # Conformance Item T24 --echo # Conformance Item T24
# TODO: ST_Centroid() alias
SELECT AsText(Centroid(boundary)) SELECT AsText(Centroid(boundary))
FROM named_places FROM named_places
WHERE name = 'Goose Island'; WHERE name = 'Goose Island';
# TODO: WL#2377 SELECT ST_Contains(boundary, PointOnSurface(boundary))
#--echo # Conformance Item T25 FROM named_places
#SELECT Contains(boundary, PointOnSurface(boundary)) WHERE name = 'Goose Island';
#FROM named_places
#WHERE name = 'Goose Island';
--echo # Conformance Item T26 --echo # Conformance Item T26
# TODO: ST_Area() alias
SELECT Area(boundary) SELECT Area(boundary)
FROM named_places FROM named_places
WHERE name = 'Goose Island'; WHERE name = 'Goose Island';
--echo # Conformance Item T27 --echo # Conformance Item T27
# TODO: ST_ExteriorRing() alias
SELECT AsText(ExteriorRing(shore)) SELECT AsText(ExteriorRing(shore))
FROM lakes FROM lakes
WHERE name = 'Blue Lake'; WHERE name = 'Blue Lake';
--echo # Conformance Item T28 --echo # Conformance Item T28
# TODO: ST_NumInteriorRings() alias
SELECT NumInteriorRings(shore) SELECT NumInteriorRings(shore)
FROM lakes FROM lakes
WHERE name = 'Blue Lake'; WHERE name = 'Blue Lake';
--echo # Conformance Item T29 --echo # Conformance Item T29
# TODO: ST_InteriorRingN() alias
SELECT AsText(InteriorRingN(shore, 1)) SELECT AsText(InteriorRingN(shore, 1))
FROM lakes FROM lakes
WHERE name = 'Blue Lake'; WHERE name = 'Blue Lake';
--echo # Conformance Item T30 --echo # Conformance Item T30
# TODO: ST_NumGeometries() alias
SELECT NumGeometries(centerlines) SELECT NumGeometries(centerlines)
FROM divided_routes FROM divided_routes
WHERE name = 'Route 75'; WHERE name = 'Route 75';
--echo # Conformance Item T31 --echo # Conformance Item T31
# TODO: ST_GeometryN() alias
SELECT AsText(GeometryN(centerlines, 2)) SELECT AsText(GeometryN(centerlines, 2))
FROM divided_routes FROM divided_routes
WHERE name = 'Route 75'; WHERE name = 'Route 75';
--echo # Conformance Item T32 --echo # Conformance Item T32
# TODO: ST_IsClosed() alias
SELECT IsClosed(centerlines) SELECT IsClosed(centerlines)
FROM divided_routes FROM divided_routes
WHERE name = 'Route 75'; WHERE name = 'Route 75';
--echo # Conformance Item T33 --echo # Conformance Item T33
# TODO: ST_Length() alias
SELECT GLength(centerlines) SELECT GLength(centerlines)
FROM divided_routes FROM divided_routes
WHERE name = 'Route 75'; WHERE name = 'Route 75';
--echo # Conformance Item T34 --echo # Conformance Item T34
# TODO: ST_Centroid() alias
SELECT AsText(Centroid(shores)) SELECT AsText(Centroid(shores))
FROM ponds FROM ponds
WHERE fid = 120; WHERE fid = 120;
# TODO: WL#2377 # TODO: WL#2377
#--echo # Conformance Item T35 --echo # Conformance Item T35
#SELECT Contains(shores, PointOnSurface(shores)) SELECT Contains(shores, PointOnSurface(shores))
#FROM ponds FROM ponds
#WHERE fid = 120; WHERE fid = 120;
--echo # Conformance Item T36 --echo # Conformance Item T36
# TODO: ST_Area() alias
SELECT Area(shores) SELECT Area(shores)
FROM ponds FROM ponds
WHERE fid = 120; WHERE fid = 120;
--echo # Conformance Item T37 --echo # Conformance Item T37
# TODO: ST_PolyFromText() alias
SELECT ST_Equals(boundary, SELECT ST_Equals(boundary,
PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1)) PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
FROM named_places FROM named_places
...@@ -1303,22 +1275,19 @@ FROM streams, lakes ...@@ -1303,22 +1275,19 @@ FROM streams, lakes
WHERE streams.name = 'Cam Stream' WHERE streams.name = 'Cam Stream'
AND lakes.name = 'Blue Lake'; AND lakes.name = 'Blue Lake';
# FIXME: wrong result: get 0, expected 1 --echo # Conformance Item T40
#--echo # Conformance Item T40 SELECT ST_Within(footprint, boundary)
#SELECT ST_Within(boundary, footprint) FROM named_places, buildings
#FROM named_places, buildings WHERE named_places.name = 'Ashton'
#WHERE named_places.name = 'Ashton' AND buildings.address = '215 Main Street';
#AND buildings.address = '215 Main Street';
# FIXME: wrong result: get 0, expected 1 --echo # Conformance Item T41
#--echo # Conformance Item T41 SELECT ST_Overlaps(forests.boundary, named_places.boundary)
#SELECT ST_Overlaps(forests.boundary, named_places.boundary) FROM forests, named_places
#FROM forests, named_places WHERE forests.name = 'Green Forest'
#WHERE forests.name = 'Green Forest' AND named_places.name = 'Ashton';
#AND named_places.name = 'Ashton';
--echo # Conformance Item T42 --echo # Conformance Item T42
# FIXME: TODO: ST_Crosses() alias
SELECT Crosses(road_segments.centerline, divided_routes.centerlines) SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
FROM road_segments, divided_routes FROM road_segments, divided_routes
WHERE road_segments.fid = 102 WHERE road_segments.fid = 102
...@@ -1336,12 +1305,11 @@ FROM forests, named_places ...@@ -1336,12 +1305,11 @@ FROM forests, named_places
WHERE forests.name = 'Green Forest' WHERE forests.name = 'Green Forest'
AND named_places.name = 'Ashton'; AND named_places.name = 'Ashton';
# TODO: WL#2377 --echo # Conformance Item T45
#--echo # Conformance Item T45 SELECT ST_Relate(forests.boundary, named_places.boundary, 'TTTTTTTTT')
#SELECT Relate(forests.boundary, named_places.boundary, 'TTTTTTTTT') FROM forests, named_places
#FROM forests, named_places WHERE forests.name = 'Green Forest'
#WHERE forests.name = 'Green Forest' AND named_places.name = 'Ashton';
#AND named_places.name = 'Ashton';
--echo # Conformance Item T46 --echo # Conformance Item T46
SELECT ST_Distance(position, boundary) SELECT ST_Distance(position, boundary)
...@@ -1349,12 +1317,11 @@ FROM bridges, named_places ...@@ -1349,12 +1317,11 @@ FROM bridges, named_places
WHERE bridges.name = 'Cam Bridge' WHERE bridges.name = 'Cam Bridge'
AND named_places.name = 'Ashton'; AND named_places.name = 'Ashton';
# FIXME: wrong result: NULL, expected 12 --echo # Conformance Item T47
#--echo # Conformance Item T47 SELECT AsText(ST_Intersection(centerline, shore))
#SELECT AsText(ST_Intersection(centerline, shore)) FROM streams, lakes
#FROM streams, lakes WHERE streams.name = 'Cam Stream'
#WHERE streams.name = 'Cam Stream' AND lakes.name = 'Blue Lake';
#AND lakes.name = 'Blue Lake';
--echo # Conformance Item T48 --echo # Conformance Item T48
SELECT AsText(ST_Difference(named_places.boundary, forests.boundary)) SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
...@@ -1379,11 +1346,10 @@ SELECT count(*) ...@@ -1379,11 +1346,10 @@ SELECT count(*)
FROM buildings, bridges FROM buildings, bridges
WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1; WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
# TODO: WL#2377 --echo # Conformance Item T52
#--echo # Conformance Item T52 SELECT AsText(ConvexHull(shore))
#SELECT AsText(ConvexHull(shore)) FROM lakes
#FROM lakes WHERE lakes.name = 'Blue Lake';
#WHERE lakes.name = 'Blue Lake';
DROP DATABASE gis_ogs; DROP DATABASE gis_ogs;
USE test; USE test;
......
...@@ -1961,7 +1961,7 @@ double Gcalc_scan_iterator::get_h() const ...@@ -1961,7 +1961,7 @@ double Gcalc_scan_iterator::get_h() const
state.pi->calc_xy(&x, &next_y); state.pi->calc_xy(&x, &next_y);
} }
else else
next_y= state.pi->y; next_y= state.pi->next ? state.pi->get_next()->y : 0.0;
return next_y - cur_y; return next_y - cur_y;
} }
...@@ -1974,7 +1974,7 @@ double Gcalc_scan_iterator::get_sp_x(const point *sp) const ...@@ -1974,7 +1974,7 @@ double Gcalc_scan_iterator::get_sp_x(const point *sp) const
dy= sp->next_pi->y - sp->pi->y; dy= sp->next_pi->y - sp->pi->y;
if (fabs(dy) < 1e-12) if (fabs(dy) < 1e-12)
return sp->pi->x; return sp->pi->x;
return (sp->next_pi->x - sp->pi->x) * dy; return sp->pi->x + (sp->next_pi->x - sp->pi->x) * dy;
} }
......
...@@ -513,7 +513,35 @@ protected: ...@@ -513,7 +513,35 @@ protected:
Create_func_centroid() {} Create_func_centroid() {}
virtual ~Create_func_centroid() {} virtual ~Create_func_centroid() {}
}; };
#endif
class Create_func_convexhull : public Create_func_arg1
{
public:
virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_convexhull s_singleton;
protected:
Create_func_convexhull() {}
virtual ~Create_func_convexhull() {}
};
class Create_func_pointonsurface : public Create_func_arg1
{
public:
virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_pointonsurface s_singleton;
protected:
Create_func_pointonsurface() {}
virtual ~Create_func_pointonsurface() {}
};
#endif /*HAVE_SPATIAL*/
class Create_func_char_length : public Create_func_arg1 class Create_func_char_length : public Create_func_arg1
...@@ -1015,7 +1043,19 @@ protected: ...@@ -1015,7 +1043,19 @@ protected:
Create_func_envelope() {} Create_func_envelope() {}
virtual ~Create_func_envelope() {} virtual ~Create_func_envelope() {}
}; };
#endif
class Create_func_boundary : public Create_func_arg1
{
public:
virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_boundary s_singleton;
protected:
Create_func_boundary() {}
virtual ~Create_func_boundary() {}
};
#endif /*HAVE_SPATIAL*/
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
...@@ -1466,6 +1506,19 @@ protected: ...@@ -1466,6 +1506,19 @@ protected:
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
class Create_func_relate : public Create_func_arg3
{
public:
virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_relate s_singleton;
protected:
Create_func_relate() {}
virtual ~Create_func_relate() {}
};
class Create_func_mbr_intersects : public Create_func_arg2 class Create_func_mbr_intersects : public Create_func_arg2
{ {
public: public:
...@@ -1596,6 +1649,19 @@ protected: ...@@ -1596,6 +1649,19 @@ protected:
Create_func_isclosed() {} Create_func_isclosed() {}
virtual ~Create_func_isclosed() {} virtual ~Create_func_isclosed() {}
}; };
class Create_func_isring : public Create_func_arg1
{
public:
virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isring s_singleton;
protected:
Create_func_isring() {}
virtual ~Create_func_isring() {}
};
#endif #endif
...@@ -3338,7 +3404,25 @@ Create_func_centroid::create_1_arg(THD *thd, Item *arg1) ...@@ -3338,7 +3404,25 @@ Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
{ {
return new (thd->mem_root) Item_func_centroid(arg1); return new (thd->mem_root) Item_func_centroid(arg1);
} }
#endif
Create_func_convexhull Create_func_convexhull::s_singleton;
Item*
Create_func_convexhull::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_convexhull(arg1);
}
Create_func_pointonsurface Create_func_pointonsurface::s_singleton;
Item*
Create_func_pointonsurface::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_pointonsurface(arg1);
}
#endif /*HAVE_SPATIAL*/
Create_func_char_length Create_func_char_length::s_singleton; Create_func_char_length Create_func_char_length::s_singleton;
...@@ -3819,6 +3903,15 @@ Create_func_envelope::create_1_arg(THD *thd, Item *arg1) ...@@ -3819,6 +3903,15 @@ Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
{ {
return new (thd->mem_root) Item_func_envelope(arg1); return new (thd->mem_root) Item_func_envelope(arg1);
} }
Create_func_boundary Create_func_boundary::s_singleton;
Item*
Create_func_boundary::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_boundary(arg1);
}
#endif #endif
...@@ -4329,6 +4422,15 @@ Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2) ...@@ -4329,6 +4422,15 @@ Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
Create_func_relate Create_func_relate::s_singleton;
Item*
Create_func_relate::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *matrix)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2, matrix);
}
Create_func_mbr_intersects Create_func_mbr_intersects::s_singleton; Create_func_mbr_intersects Create_func_mbr_intersects::s_singleton;
Item* Item*
...@@ -4429,10 +4531,17 @@ Create_func_isclosed::create_1_arg(THD *thd, Item *arg1) ...@@ -4429,10 +4531,17 @@ Create_func_isclosed::create_1_arg(THD *thd, Item *arg1)
{ {
return new (thd->mem_root) Item_func_isclosed(arg1); return new (thd->mem_root) Item_func_isclosed(arg1);
} }
#endif
#ifdef HAVE_SPATIAL Create_func_isring Create_func_isring::s_singleton;
Item*
Create_func_isring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isring(arg1);
}
Create_func_isempty Create_func_isempty::s_singleton; Create_func_isempty Create_func_isempty::s_singleton;
Item* Item*
...@@ -4440,7 +4549,7 @@ Create_func_isempty::create_1_arg(THD *thd, Item *arg1) ...@@ -4440,7 +4549,7 @@ Create_func_isempty::create_1_arg(THD *thd, Item *arg1)
{ {
return new (thd->mem_root) Item_func_isempty(arg1); return new (thd->mem_root) Item_func_isempty(arg1);
} }
#endif #endif /*HAVE_SPATIAL*/
Create_func_isnull Create_func_isnull::s_singleton; Create_func_isnull Create_func_isnull::s_singleton;
...@@ -5656,6 +5765,7 @@ static Native_func_registry func_array[] = ...@@ -5656,6 +5765,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("BINLOG_GTID_POS") }, BUILDER(Create_func_binlog_gtid_pos)}, { { C_STRING_WITH_LEN("BINLOG_GTID_POS") }, BUILDER(Create_func_binlog_gtid_pos)},
{ { C_STRING_WITH_LEN("BIT_COUNT") }, BUILDER(Create_func_bit_count)}, { { C_STRING_WITH_LEN("BIT_COUNT") }, BUILDER(Create_func_bit_count)},
{ { C_STRING_WITH_LEN("BIT_LENGTH") }, BUILDER(Create_func_bit_length)}, { { C_STRING_WITH_LEN("BIT_LENGTH") }, BUILDER(Create_func_bit_length)},
{ { C_STRING_WITH_LEN("BOUNDARY") }, GEOM_BUILDER(Create_func_boundary)},
{ { C_STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)}, { { C_STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
{ { C_STRING_WITH_LEN("CEIL") }, BUILDER(Create_func_ceiling)}, { { C_STRING_WITH_LEN("CEIL") }, BUILDER(Create_func_ceiling)},
{ { C_STRING_WITH_LEN("CEILING") }, BUILDER(Create_func_ceiling)}, { { C_STRING_WITH_LEN("CEILING") }, BUILDER(Create_func_ceiling)},
...@@ -5673,6 +5783,7 @@ static Native_func_registry func_array[] = ...@@ -5673,6 +5783,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("CONNECTION_ID") }, BUILDER(Create_func_connection_id)}, { { C_STRING_WITH_LEN("CONNECTION_ID") }, BUILDER(Create_func_connection_id)},
{ { C_STRING_WITH_LEN("CONV") }, BUILDER(Create_func_conv)}, { { C_STRING_WITH_LEN("CONV") }, BUILDER(Create_func_conv)},
{ { C_STRING_WITH_LEN("CONVERT_TZ") }, BUILDER(Create_func_convert_tz)}, { { C_STRING_WITH_LEN("CONVERT_TZ") }, BUILDER(Create_func_convert_tz)},
{ { C_STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
{ { C_STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)}, { { C_STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)},
{ { C_STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)}, { { C_STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)},
{ { C_STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)}, { { C_STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)},
...@@ -5737,6 +5848,7 @@ static Native_func_registry func_array[] = ...@@ -5737,6 +5848,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)}, { { C_STRING_WITH_LEN("ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
{ { C_STRING_WITH_LEN("ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)}, { { C_STRING_WITH_LEN("ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
{ { C_STRING_WITH_LEN("ISNULL") }, BUILDER(Create_func_isnull)}, { { C_STRING_WITH_LEN("ISNULL") }, BUILDER(Create_func_isnull)},
{ { C_STRING_WITH_LEN("ISRING") }, GEOM_BUILDER(Create_func_isring)},
{ { C_STRING_WITH_LEN("ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)}, { { C_STRING_WITH_LEN("ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
{ { C_STRING_WITH_LEN("IS_FREE_LOCK") }, BUILDER(Create_func_is_free_lock)}, { { C_STRING_WITH_LEN("IS_FREE_LOCK") }, BUILDER(Create_func_is_free_lock)},
{ { C_STRING_WITH_LEN("IS_USED_LOCK") }, BUILDER(Create_func_is_used_lock)}, { { C_STRING_WITH_LEN("IS_USED_LOCK") }, BUILDER(Create_func_is_used_lock)},
...@@ -5803,6 +5915,7 @@ static Native_func_registry func_array[] = ...@@ -5803,6 +5915,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { C_STRING_WITH_LEN("POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)}, { { C_STRING_WITH_LEN("POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { C_STRING_WITH_LEN("POINTN") }, GEOM_BUILDER(Create_func_pointn)}, { { C_STRING_WITH_LEN("POINTN") }, GEOM_BUILDER(Create_func_pointn)},
{ { C_STRING_WITH_LEN("POINTONSURFACE") }, GEOM_BUILDER(Create_func_pointonsurface)},
{ { C_STRING_WITH_LEN("POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { C_STRING_WITH_LEN("POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)}, { { C_STRING_WITH_LEN("POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { C_STRING_WITH_LEN("POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
...@@ -5839,9 +5952,11 @@ static Native_func_registry func_array[] = ...@@ -5839,9 +5952,11 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("ST_ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)}, { { C_STRING_WITH_LEN("ST_ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)},
{ { C_STRING_WITH_LEN("ST_ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)}, { { C_STRING_WITH_LEN("ST_ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)},
{ { C_STRING_WITH_LEN("ST_ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)}, { { C_STRING_WITH_LEN("ST_ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)},
{ { C_STRING_WITH_LEN("ST_BOUNDARY") }, GEOM_BUILDER(Create_func_boundary)},
{ { C_STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)}, { { C_STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
{ { C_STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)}, { { C_STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
{ { C_STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)}, { { C_STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
{ { C_STRING_WITH_LEN("ST_CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
{ { C_STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)}, { { C_STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
{ { C_STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)}, { { C_STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)},
{ { C_STRING_WITH_LEN("ST_DIMENSION") }, GEOM_BUILDER(Create_func_dimension)}, { { C_STRING_WITH_LEN("ST_DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
...@@ -5870,6 +5985,7 @@ static Native_func_registry func_array[] = ...@@ -5870,6 +5985,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("ST_INTERSECTION") }, GEOM_BUILDER(Create_func_intersection)}, { { C_STRING_WITH_LEN("ST_INTERSECTION") }, GEOM_BUILDER(Create_func_intersection)},
{ { C_STRING_WITH_LEN("ST_ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)}, { { C_STRING_WITH_LEN("ST_ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
{ { C_STRING_WITH_LEN("ST_ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)}, { { C_STRING_WITH_LEN("ST_ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
{ { C_STRING_WITH_LEN("ST_ISRING") }, GEOM_BUILDER(Create_func_isring)},
{ { C_STRING_WITH_LEN("ST_ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)}, { { C_STRING_WITH_LEN("ST_ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
{ { C_STRING_WITH_LEN("ST_LENGTH") }, GEOM_BUILDER(Create_func_glength)}, { { C_STRING_WITH_LEN("ST_LENGTH") }, GEOM_BUILDER(Create_func_glength)},
{ { C_STRING_WITH_LEN("ST_LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("ST_LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
...@@ -5883,10 +5999,12 @@ static Native_func_registry func_array[] = ...@@ -5883,10 +5999,12 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("ST_POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("ST_POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { C_STRING_WITH_LEN("ST_POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)}, { { C_STRING_WITH_LEN("ST_POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { C_STRING_WITH_LEN("ST_POINTN") }, GEOM_BUILDER(Create_func_pointn)}, { { C_STRING_WITH_LEN("ST_POINTN") }, GEOM_BUILDER(Create_func_pointn)},
{ { C_STRING_WITH_LEN("ST_POINTONSURFACE") }, GEOM_BUILDER(Create_func_pointonsurface)},
{ { C_STRING_WITH_LEN("ST_POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("ST_POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { C_STRING_WITH_LEN("ST_POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)}, { { C_STRING_WITH_LEN("ST_POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { C_STRING_WITH_LEN("ST_POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("ST_POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { C_STRING_WITH_LEN("ST_POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)}, { { C_STRING_WITH_LEN("ST_POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { C_STRING_WITH_LEN("ST_RELATE") }, GEOM_BUILDER(Create_func_relate)},
{ { C_STRING_WITH_LEN("ST_SRID") }, GEOM_BUILDER(Create_func_srid)}, { { C_STRING_WITH_LEN("ST_SRID") }, GEOM_BUILDER(Create_func_srid)},
{ { C_STRING_WITH_LEN("ST_STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)}, { { C_STRING_WITH_LEN("ST_STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
{ { C_STRING_WITH_LEN("ST_SYMDIFFERENCE") }, GEOM_BUILDER(Create_func_symdifference)}, { { C_STRING_WITH_LEN("ST_SYMDIFFERENCE") }, GEOM_BUILDER(Create_func_symdifference)},
......
...@@ -61,7 +61,7 @@ public: ...@@ -61,7 +61,7 @@ public:
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC, SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING, SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_RELATE_FUNC,
NOT_FUNC, NOT_ALL_FUNC, NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC, NOW_FUNC, TRIG_COND_FUNC,
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
......
This diff is collapsed.
...@@ -93,6 +93,39 @@ public: ...@@ -93,6 +93,39 @@ public:
}; };
}; };
// #define HEAVY_CONVEX_HULL
class Item_func_convexhull: public Item_geometry_func
{
class ch_node: public Gcalc_dyn_list::Item
{
public:
const Gcalc_heap::Info *pi;
ch_node *prev;
Gcalc_dyn_list::Item *next;
ch_node *get_next() { return (ch_node *) next; }
};
Gcalc_heap collector;
Gcalc_function func;
Gcalc_dyn_list res_heap;
Gcalc_result_receiver res_receiver;
String tmp_value;
#ifdef HEAVY_CONVEX_HULL
Gcalc_scan_iterator scan_it;
#endif /*HEAVY_CONVEX_HULL*/
ch_node *new_ch_node() { return (ch_node *) res_heap.new_item(); }
int add_node_to_line(ch_node **p_cur, int dir, const Gcalc_heap::Info *pi);
public:
Item_func_convexhull(Item *a): Item_geometry_func(a),
res_heap(8192, sizeof(ch_node))
{}
const char *func_name() const { return "st_convexhull"; }
String *val_str(String *);
};
class Item_func_centroid: public Item_geometry_func class Item_func_centroid: public Item_geometry_func
{ {
public: public:
...@@ -111,6 +144,38 @@ public: ...@@ -111,6 +144,38 @@ public:
Field::geometry_type get_geometry_type() const; Field::geometry_type get_geometry_type() const;
}; };
class Item_func_boundary: public Item_geometry_func
{
class Transporter : public Gcalc_shape_transporter
{
Gcalc_result_receiver *m_receiver;
uint n_points;
Gcalc_function::shape_type current_type;
double last_x, last_y;
public:
Transporter(Gcalc_result_receiver *receiver) :
Gcalc_shape_transporter(NULL), m_receiver(receiver)
{}
int single_point(double x, double y);
int start_line();
int complete_line();
int start_poly();
int complete_poly();
int start_ring();
int complete_ring();
int add_point(double x, double y);
int start_collection(int n_objects);
};
Gcalc_result_receiver res_receiver;
public:
Item_func_boundary(Item *a): Item_geometry_func(a) {}
const char *func_name() const { return "st_boundary"; }
String *val_str(String *);
};
class Item_func_point: public Item_geometry_func class Item_func_point: public Item_geometry_func
{ {
public: public:
...@@ -229,15 +294,16 @@ public: ...@@ -229,15 +294,16 @@ public:
}; };
class Item_func_spatial_rel: public Item_bool_func2 class Item_func_spatial_rel: public Item_int_func
{ {
enum Functype spatial_rel; enum Functype spatial_rel;
Gcalc_heap collector; Gcalc_heap collector;
Gcalc_scan_iterator scan_it; Gcalc_scan_iterator scan_it;
Gcalc_function func; Gcalc_function func;
String tmp_value1,tmp_value2; String tmp_value1,tmp_value2, tmp_matrix;
public: public:
Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel); Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel);
Item_func_spatial_rel(Item *a, Item *b, Item *matrix);
virtual ~Item_func_spatial_rel(); virtual ~Item_func_spatial_rel();
longlong val_int(); longlong val_int();
enum Functype functype() const enum Functype functype() const
...@@ -253,6 +319,9 @@ public: ...@@ -253,6 +319,9 @@ public:
void fix_length_and_dec() { maybe_null= 1; } void fix_length_and_dec() { maybe_null= 1; }
bool is_null() { (void) val_int(); return null_value; } bool is_null() { (void) val_int(); return null_value; }
bool is_bool_func() { return 1; }
uint decimal_precision() const { return 1; }
optimize_type select_optimize() const { return OPTIMIZE_OP; }
}; };
...@@ -369,6 +438,14 @@ public: ...@@ -369,6 +438,14 @@ public:
void fix_length_and_dec() { maybe_null= 1; } void fix_length_and_dec() { maybe_null= 1; }
}; };
class Item_func_isring: public Item_func_issimple
{
public:
Item_func_isring(Item *a): Item_func_issimple(a) {}
longlong val_int();
const char *func_name() const { return "st_isring"; }
};
class Item_func_dimension: public Item_int_func class Item_func_dimension: public Item_int_func
{ {
String value; String value;
...@@ -497,6 +574,20 @@ public: ...@@ -497,6 +574,20 @@ public:
}; };
class Item_func_pointonsurface: public Item_geometry_func
{
String tmp_value;
Gcalc_heap collector;
Gcalc_function func;
Gcalc_scan_iterator scan_it;
public:
Item_func_pointonsurface(Item *a): Item_geometry_func(a) {}
const char *func_name() const { return "st_pointonsurface"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
};
#ifndef DBUG_OFF #ifndef DBUG_OFF
class Item_func_gis_debug: public Item_int_func class Item_func_gis_debug: public Item_int_func
{ {
......
...@@ -291,19 +291,18 @@ Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer, ...@@ -291,19 +291,18 @@ Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer,
} }
int Geometry::create_from_opresult(Geometry_buffer *g_buf, Geometry *Geometry::create_from_opresult(Geometry_buffer *g_buf,
String *res, Gcalc_result_receiver &rr) String *res, Gcalc_result_receiver &rr)
{ {
uint32 geom_type= rr.get_result_typeid(); uint32 geom_type= rr.get_result_typeid();
Geometry *obj= create_by_typeid(g_buf, geom_type); Geometry *obj= create_by_typeid(g_buf, geom_type);
if (!obj || res->reserve(WKB_HEADER_SIZE, 512)) if (!obj || res->reserve(WKB_HEADER_SIZE, 512))
return 1; return NULL;
res->q_append((char) wkb_ndr); res->q_append((char) wkb_ndr);
res->q_append(geom_type); res->q_append(geom_type);
return obj->init_from_opresult(res, rr.result(), rr.length()) == 0 && return obj->init_from_opresult(res, rr.result(), rr.length()) ? obj : NULL;
rr.length();
} }
...@@ -386,7 +385,7 @@ bool Geometry::create_point(String *result, const char *data) const ...@@ -386,7 +385,7 @@ bool Geometry::create_point(String *result, const char *data) const
1 Can't reallocate 'result' 1 Can't reallocate 'result'
*/ */
bool Geometry::create_point(String *result, double x, double y) const bool Geometry::create_point(String *result, double x, double y)
{ {
if (result->reserve(1 + 4 + POINT_DATA_SIZE)) if (result->reserve(1 + 4 + POINT_DATA_SIZE))
return 1; return 1;
...@@ -2221,6 +2220,13 @@ uint Gis_geometry_collection::init_from_opresult(String *bin, ...@@ -2221,6 +2220,13 @@ uint Gis_geometry_collection::init_from_opresult(String *bin,
return 0; return 0;
bin->q_append(n_objects); bin->q_append(n_objects);
if (res_len == 0)
{
/* Special case of GEOMETRYCOLLECTION EMPTY. */
opres+= 1;
goto empty_geom;
}
while (res_len) while (res_len)
{ {
switch ((Gcalc_function::shape_type) uint4korr(opres)) switch ((Gcalc_function::shape_type) uint4korr(opres))
...@@ -2244,6 +2250,7 @@ uint Gis_geometry_collection::init_from_opresult(String *bin, ...@@ -2244,6 +2250,7 @@ uint Gis_geometry_collection::init_from_opresult(String *bin,
res_len-= g_len; res_len-= g_len;
n_objects++; n_objects++;
} }
empty_geom:
bin->write_at_position(no_pos, n_objects); bin->write_at_position(no_pos, n_objects);
return (uint) (opres - opres_orig); return (uint) (opres - opres_orig);
} }
......
...@@ -298,7 +298,7 @@ public: ...@@ -298,7 +298,7 @@ public:
bool init_stream=1); bool init_stream=1);
static Geometry *create_from_wkb(Geometry_buffer *buffer, static Geometry *create_from_wkb(Geometry_buffer *buffer,
const char *wkb, uint32 len, String *res); const char *wkb, uint32 len, String *res);
static int create_from_opresult(Geometry_buffer *g_buf, static Geometry *create_from_opresult(Geometry_buffer *g_buf,
String *res, Gcalc_result_receiver &rr); String *res, Gcalc_result_receiver &rr);
int as_wkt(String *wkt, const char **end); int as_wkt(String *wkt, const char **end);
...@@ -316,6 +316,7 @@ public: ...@@ -316,6 +316,7 @@ public:
bool envelope(String *result) const; bool envelope(String *result) const;
static Class_info *ci_collection[wkb_last+1]; static Class_info *ci_collection[wkb_last+1];
static bool create_point(String *result, double x, double y);
protected: protected:
static Class_info *find_class(int type_id) static Class_info *find_class(int type_id)
{ {
...@@ -326,7 +327,6 @@ protected: ...@@ -326,7 +327,6 @@ protected:
const char *append_points(String *txt, uint32 n_points, const char *append_points(String *txt, uint32 n_points,
const char *data, uint32 offset) const; const char *data, uint32 offset) const;
bool create_point(String *result, const char *data) const; bool create_point(String *result, const char *data) const;
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment