summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2017-07-25 10:57:25 +0400
committerSergei Golubchik <serg@mariadb.org>2017-08-01 09:52:56 +0200
commit7f5a8f176ac59f0a15fb3723b5b2ab47b4fbe9e0 (patch)
treefc7f6b39adeec16cd094c9ee760841d813057eae
parentf8736063deab07744e5e3c8834d60a1db5a8574d (diff)
downloadmariadb-git-7f5a8f176ac59f0a15fb3723b5b2ab47b4fbe9e0.tar.gz
MDEV-12915 ST_Centroid does not return the same result than MySQL.
Calculation of the polygon's centroid fixed.
-rw-r--r--mysql-test/r/gis.result8
-rw-r--r--mysql-test/suite/archive/archive_gis.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb_gis.result4
-rw-r--r--sql/spatial.cc27
4 files changed, 29 insertions, 14 deletions
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index f029542e717..f77cd4d14bf 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -333,8 +333,8 @@ fid IsClosed(g)
116 0
SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
fid AsText(Centroid(g))
-117 POINT(55.58852775304245 17.426536064113982)
-118 POINT(55.58852775304245 17.426536064113982)
+117 POINT(57.98031067576927 17.854754130800433)
+118 POINT(57.98031067576927 17.854754130800433)
119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon;
fid Area(g)
@@ -684,11 +684,11 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85998;
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
-85998 MULTIPOLYGON 1 POINT(115.31877315203187 -36.23747282102153)
+85998 MULTIPOLYGON 1 POINT(115.2970604672862 -36.23335610879993)
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85984;
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
-85984 MULTIPOLYGON 1 POINT(-114.87787186923313 36.33101763469059)
+85984 MULTIPOLYGON 1 POINT(-114.86854472054372 36.34725218253213)
drop table t1;
create table t1 (fl geometry not null);
insert into t1 values (1);
diff --git a/mysql-test/suite/archive/archive_gis.result b/mysql-test/suite/archive/archive_gis.result
index 97f48407db2..5593b53f7c3 100644
--- a/mysql-test/suite/archive/archive_gis.result
+++ b/mysql-test/suite/archive/archive_gis.result
@@ -326,8 +326,8 @@ fid IsClosed(g)
116 0
SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
fid AsText(Centroid(g))
-117 POINT(55.58852775304245 17.426536064113982)
-118 POINT(55.58852775304245 17.426536064113982)
+117 POINT(57.98031067576927 17.854754130800433)
+118 POINT(57.98031067576927 17.854754130800433)
119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid;
fid Area(g)
diff --git a/mysql-test/suite/innodb/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result
index 21c1234d7d3..f683195ac15 100644
--- a/mysql-test/suite/innodb/r/innodb_gis.result
+++ b/mysql-test/suite/innodb/r/innodb_gis.result
@@ -326,8 +326,8 @@ fid IsClosed(g)
116 0
SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
fid AsText(Centroid(g))
-117 POINT(55.58852775304245 17.426536064113982)
-118 POINT(55.58852775304245 17.426536064113982)
+117 POINT(57.98031067576927 17.854754130800433)
+118 POINT(57.98031067576927 17.854754130800433)
119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid;
fid Area(g)
diff --git a/sql/spatial.cc b/sql/spatial.cc
index bfe302f332e..b03a8b6da07 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -1150,8 +1150,8 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
uint32 n_points, org_n_points;
double prev_x, prev_y;
double cur_area= 0;
- double cur_cx= 0;
- double cur_cy= 0;
+ double cur_cx= 0, cur_cy= 0;
+ double sum_cx= 0, sum_cy= 0;
if (no_data(data, 4))
return 1;
@@ -1165,17 +1165,32 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
while (--n_points) // One point is already read
{
double tmp_x, tmp_y;
+ double loc_area;
get_point(&tmp_x, &tmp_y, data);
data+= POINT_DATA_SIZE;
- cur_area+= (prev_x + tmp_x) * (prev_y - tmp_y);
+ loc_area= prev_x * tmp_y - tmp_x * prev_y;
+ cur_area+= loc_area;
cur_cx+= tmp_x;
cur_cy+= tmp_y;
+ sum_cx+= (prev_x + tmp_x) * loc_area;
+ sum_cy+= (prev_y + tmp_y) * loc_area;
+
prev_x= tmp_x;
prev_y= tmp_y;
}
- cur_area= fabs(cur_area) / 2;
- cur_cx= cur_cx / (org_n_points - 1);
- cur_cy= cur_cy / (org_n_points - 1);
+
+ if (fabs(cur_area) > 1e-10)
+ {
+ cur_cx= sum_cx / cur_area / 3.0;
+ cur_cy= sum_cy / cur_area / 3.0;
+ }
+ else
+ {
+ cur_cx= cur_cx / (org_n_points - 1);
+ cur_cy= cur_cy / (org_n_points - 1);
+ }
+
+ cur_area= fabs(cur_area);
if (!first_loop)
{