diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2017-07-25 10:57:25 +0400 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-08-01 09:52:56 +0200 |
commit | 7f5a8f176ac59f0a15fb3723b5b2ab47b4fbe9e0 (patch) | |
tree | fc7f6b39adeec16cd094c9ee760841d813057eae | |
parent | f8736063deab07744e5e3c8834d60a1db5a8574d (diff) | |
download | mariadb-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.result | 8 | ||||
-rw-r--r-- | mysql-test/suite/archive/archive_gis.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb_gis.result | 4 | ||||
-rw-r--r-- | sql/spatial.cc | 27 |
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) { |