Commit f2366bf0 authored by hf@deer.(none)'s avatar hf@deer.(none)

Spatial code changed to get rid of inconsistent this->* operation

Now we use virtual calls instead and redirect VMT pointer of the
geometry object with 'new' operation
parent 082a01d1
...@@ -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::wkbPoint || if (wkb_type < (uint32) Geometry::wkb_point ||
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);
......
...@@ -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::wkbNDR); str->q_append((char)Geometry::wkb_ndr);
str->q_append((uint32)Geometry::wkbPoint); str->q_append((uint32)Geometry::wkb_point);
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::wkbNDR); 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::wkbGeometryCollection) if (coll_type == Geometry::wkb_geometrycollection)
{ {
/* /*
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::wkbMultiPoint: case Geometry::wkb_multipoint:
case Geometry::wkbMultiLineString: case Geometry::wkb_multilinestring:
case Geometry::wkbMultiPolygon: case Geometry::wkb_multipolygon:
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::wkbLineString: case Geometry::wkb_linestring:
if (str->append(data, POINT_DATA_SIZE, 512)) if (str->append(data, POINT_DATA_SIZE, 512))
goto err; goto err;
break; break;
case Geometry::wkbPolygon: case Geometry::wkb_polygon:
{ {
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[1]->null_value || (args[0]->null_value ||
g1.create_from_wkb(res1->ptr() + SRID_SIZE, args[1]->null_value ||
res1->length() - SRID_SIZE) || !(g1= Geometry::create_from_wkb(&buffer1, res1->ptr() + SRID_SIZE,
g2.create_from_wkb(res2->ptr() + SRID_SIZE, res1->length() - SRID_SIZE)) ||
res2->length() - SRID_SIZE) || !(g2= Geometry::create_from_wkb(&buffer2, res2->ptr() + SRID_SIZE,
g1.get_mbr(&mbr1, &dummy) || res2->length() - SRID_SIZE)) ||
g2.get_mbr(&mbr2, &dummy)))) g1->get_mbr(&mbr1, &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,24 +658,27 @@ double Item_func_glength::val() ...@@ -632,24 +658,27 @@ 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->length() - SRID_SIZE)); swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE));
if (null_value) if (null_value)
return 0; return 0;
......
...@@ -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;
} }
Geometry::Gis_class_info *Geometry::find_class(const char *name, uint32 len) static void create_multipolygon(void *buffer)
{ {
for (Gis_class_info *cur_rt= ci_collection; cur_rt < ci_collection_end; cur_rt++) new(buffer) Gis_multi_polygon;
}
static void create_multilinestring(void *buffer)
{
new(buffer) Gis_multi_line_string;
}
static void create_geometrycollection(void *buffer)
{
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,
bool init_stream) Gis_read_stream *trs, String *wkt,
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) wkbNDR); result->q_append((char) wkb_ndr);
result->q_append((uint32) wkbPolygon); result->q_append((uint32) wkb_polygon);
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) wkbNDR); result->q_append((char) wkb_ndr);
result->q_append((uint32) wkbPoint); result->q_append((uint32) wkb_point);
/* 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) wkbNDR); result->q_append((char) wkb_ndr);
result->q_append((uint32) wkbPoint); result->q_append((uint32) wkb_point);
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) wkbNDR); result->q_append((char) wkb_ndr);
result->q_append((uint32) wkbLineString); result->q_append((uint32) wkb_linestring);
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) wkbNDR); result->q_append((char) wkb_ndr);
result->q_append((uint32) wkbLineString); result->q_append((uint32) wkb_linestring);
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) wkbNDR); wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkbPoint); wkb->q_append((uint32) wkb_point);
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_stringg::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_stringg::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) wkbNDR); wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkbLineString); wkb->q_append((uint32) wkb_linestring);
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_stringg::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_stringg::num_geometries(uint32 *num) const int Gis_multi_line_string::num_geometries(uint32 *num) const
{ {
*num= uint4korr(m_data); *num= uint4korr(m_data);
return 0; return 0;
} }
bool Gis_multi_line_stringg::geometry_n(uint32 num, String *result) const int Gis_multi_line_string::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_stringg::length(double *len) const int Gis_multi_line_string::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_stringg::is_closed(int *closed) const int Gis_multi_line_string::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) wkbNDR); wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkbPolygon); wkb->q_append((uint32) wkb_polygon);
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 == wkbGeometryCollection) if (g->get_class_info()->m_type_id == wkb_geometrycollection)
{ {
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) wkbNDR); 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;
}
...@@ -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
{ {
wkbPoint= 1, wkb_point= 1,
wkbLineString= 2, wkb_linestring= 2,
wkbPolygon= 3, wkb_polygon= 3,
wkbMultiPoint= 4, wkb_multipoint= 4,
wkbMultiLineString= 5, wkb_multilinestring= 5,
wkbMultiPolygon= 6, wkb_multipolygon= 6,
wkbGeometryCollection= 7, wkb_geometrycollection= 7,
wkb_end=8 wkb_end=7
}; };
enum wkbByteOrder enum wkbByteOrder
{ {
wkbXDR= 0, /* Big Endian */ wkb_xdr= 0, /* Big Endian */
wkbNDR= 1 /* Little Endian */ wkb_ndr= 1 /* Little Endian */
}; };
class Gis_class_info class Class_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)
{ return (this->*m_vmt->init_from_wkt)(trs, wkb); }
bool get_data_as_wkt(String *txt, const char **end)
{ return (this->*m_vmt->get_data_as_wkt)(txt, end); }
int get_mbr(MBR *mbr, const char **end) const
{ return (this->*m_vmt->get_mbr)(mbr, end); }
bool dimension(uint32 *dim, const char **end) const
{
return (this->*m_vmt->dimension)(dim, end);
}
bool get_x(double *x) const { return (this->*m_vmt->get_x)(x); } virtual const Class_info *get_class_info() const=0;
bool get_y(double *y) const { return (this->*m_vmt->get_y)(y); } virtual uint32 get_data_size() const=0;
bool length(double *len) const { return (this->*m_vmt->length)(len); } virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0;
bool area(double *ar, const char **end) const virtual bool get_data_as_wkt(String *txt, const char **end) const=0;
{ virtual bool get_mbr(MBR *mbr, const char **end) const=0;
return (this->*m_vmt->area)(ar, end); virtual bool dimension(uint32 *dim, const char **end) const=0;
} virtual int get_x(double *x) const { return -1; }
virtual int get_y(double *y) const { return -1; }
bool is_closed(int *closed) const virtual int length(double *len) const { return -1; }
{ return (this->*m_vmt->is_closed)(closed); } virtual int area(double *ar, const char **end) const { return -1;}
virtual int is_closed(int *closed) const { return -1; }
bool num_interior_ring(uint32 *n_int_rings) const virtual int num_interior_ring(uint32 *n_int_rings) const { return -1; }
{ return (this->*m_vmt->num_interior_ring)(n_int_rings); } virtual int num_points(uint32 *n_points) const { return -1; }
bool num_points(uint32 *n_points) const virtual int num_geometries(uint32 *num) const { return -1; }
{ return (this->*m_vmt->num_points)(n_points); } virtual int start_point(String *point) const { return -1; }
virtual int end_point(String *point) const { return -1; }
bool num_geometries(uint32 *num) const virtual int exterior_ring(String *ring) const { return -1; }
{ return (this->*m_vmt->num_geometries)(num); } virtual int centroid(String *point) const { return -1; }
virtual int point_n(uint32 num, String *result) const { return -1; }
bool start_point(String *point) virtual int interior_ring_n(uint32 num, String *result) const { return -1; }
{ return (this->*m_vmt->start_point)(point); } virtual int geometry_n(uint32 num, String *result) const { return -1; }
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_stringg: 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
...@@ -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::wkbGeometryCollection, Geometry::wkb_geometrycollection,
Geometry::wkbPoint)); } Geometry::wkb_point)); }
| LINESTRING '(' expr_list ')' | LINESTRING '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3, { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkbLineString, Geometry::wkbPoint)); } Geometry::wkb_linestring, Geometry::wkb_point)); }
| MULTILINESTRING '(' expr_list ')' | MULTILINESTRING '(' expr_list ')'
{ $$= GEOM_NEW( Item_func_spatial_collection(* $3, { $$= GEOM_NEW( Item_func_spatial_collection(* $3,
Geometry::wkbMultiLineString, Geometry::wkbLineString)); } Geometry::wkb_multilinestring, Geometry::wkb_linestring)); }
| 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::wkbMultiPoint, Geometry::wkbPoint)); } Geometry::wkb_multipoint, Geometry::wkb_point)); }
| MULTIPOLYGON '(' expr_list ')' | MULTIPOLYGON '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3, { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkbMultiPolygon, Geometry::wkbPolygon)); } Geometry::wkb_multipolygon, Geometry::wkb_polygon)); }
| 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::wkbPolygon, Geometry::wkbLineString)); } Geometry::wkb_polygon, Geometry::wkb_linestring)); }
| 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 ')'
......
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