diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/gcalc_slicescan.cc | 2 | ||||
-rw-r--r-- | sql/spatial.cc | 60 | ||||
-rw-r--r-- | sql/spatial.h | 3 |
3 files changed, 64 insertions, 1 deletions
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc index 07120d2e87e..8a9fcc60ad0 100644 --- a/sql/gcalc_slicescan.cc +++ b/sql/gcalc_slicescan.cc @@ -2033,7 +2033,7 @@ double Gcalc_scan_iterator::get_h() const double Gcalc_scan_iterator::get_sp_x(const point *sp) const { double dy; - if (sp->event == scev_end | scev_two_ends | scev_point) + if (sp->event & (scev_end | scev_two_ends | scev_point)) return sp->pi->x; dy= sp->next_pi->y - sp->pi->y; if (fabs(dy) < 1e-12) diff --git a/sql/spatial.cc b/sql/spatial.cc index 0e535d11056..4d5e5db10c0 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -489,6 +489,14 @@ bool Gis_point::get_mbr(MBR *mbr, const char **end) const } +int Gis_point::area(double *ar, const char **end) const +{ + *ar= 0; + *end= m_data+ POINT_DATA_SIZE; + return 0; +} + + int Gis_point::store_shapes(Gcalc_shape_transporter *trn) const { double x, y; @@ -634,6 +642,20 @@ int Gis_line_string::geom_length(double *len) const } +int Gis_line_string::area(double *ar, const char **end) const +{ + uint32 n_points; + *ar= 0.0; + + /* read number of points */ + if (no_data(m_data, 4)) + return 1; + n_points= uint4korr(m_data); + *end= m_data + 4 + POINT_DATA_SIZE * n_points; + return 0; +} + + int Gis_line_string::is_closed(int *closed) const { uint32 n_points; @@ -2253,6 +2275,44 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const } +int Gis_geometry_collection::area(double *ar, const char **end_of_data) const +{ + uint32 n_objects; + const char *data= m_data; + Geometry_buffer buffer; + Geometry *geom; + double result; + + if (no_data(data, 4)) + return 1; + n_objects= uint4korr(data); + data+= 4; + if (n_objects == 0) + return 1; + + result= 0.0; + while (n_objects--) + { + uint32 wkb_type; + + if (no_data(data, WKB_HEADER_SIZE)) + return 1; + wkb_type= uint4korr(data + 1); + data+= WKB_HEADER_SIZE; + + if (!(geom= create_by_typeid(&buffer, wkb_type))) + return 1; + geom->set_data_ptr(data, (uint32) (m_data_end - data)); + if (geom->area(ar, &data)) + return 1; + result+= *ar; + } + *end_of_data= data; + *ar= result; + return 0; +} + + int Gis_geometry_collection::num_geometries(uint32 *num) const { if (no_data(m_data, 4)) diff --git a/sql/spatial.h b/sql/spatial.h index e8f230f9127..eaf048b7a3d 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -375,6 +375,7 @@ public: return 0; } + int area(double *ar, const char **end) const; bool dimension(uint32 *dim, const char **end) const { *dim= 0; @@ -399,6 +400,7 @@ public: bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; int geom_length(double *len) const; + int area(double *ar, const char **end) const; int is_closed(int *closed) const; int num_points(uint32 *n_points) const; int start_point(String *point) const; @@ -540,6 +542,7 @@ public: uint init_from_opresult(String *bin, const char *opres, uint res_len); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; + int area(double *ar, const char **end) const; int num_geometries(uint32 *num) const; int geometry_n(uint32 num, String *result) const; bool dimension(uint32 *dim, const char **end) const; |