Commit 7f5a8f17 authored by Alexey Botchkov's avatar Alexey Botchkov Committed by Sergei Golubchik

MDEV-12915 ST_Centroid does not return the same result than MySQL.

        Calculation of the polygon's centroid fixed.
parent f8736063
...@@ -333,8 +333,8 @@ fid IsClosed(g) ...@@ -333,8 +333,8 @@ fid IsClosed(g)
116 0 116 0
SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon; SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
fid AsText(Centroid(g)) fid AsText(Centroid(g))
117 POINT(55.58852775304245 17.426536064113982) 117 POINT(57.98031067576927 17.854754130800433)
118 POINT(55.58852775304245 17.426536064113982) 118 POINT(57.98031067576927 17.854754130800433)
119 POINT(2 2) 119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon; SELECT fid, Area(g) FROM gis_multi_polygon;
fid Area(g) fid Area(g)
...@@ -684,11 +684,11 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363 ...@@ -684,11 +684,11 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85998; t1 where object_id=85998;
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo)) 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 select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85984; t1 where object_id=85984;
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo)) 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; drop table t1;
create table t1 (fl geometry not null); create table t1 (fl geometry not null);
insert into t1 values (1); insert into t1 values (1);
......
...@@ -326,8 +326,8 @@ fid IsClosed(g) ...@@ -326,8 +326,8 @@ fid IsClosed(g)
116 0 116 0
SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
fid AsText(Centroid(g)) fid AsText(Centroid(g))
117 POINT(55.58852775304245 17.426536064113982) 117 POINT(57.98031067576927 17.854754130800433)
118 POINT(55.58852775304245 17.426536064113982) 118 POINT(57.98031067576927 17.854754130800433)
119 POINT(2 2) 119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid;
fid Area(g) fid Area(g)
......
...@@ -326,8 +326,8 @@ fid IsClosed(g) ...@@ -326,8 +326,8 @@ fid IsClosed(g)
116 0 116 0
SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
fid AsText(Centroid(g)) fid AsText(Centroid(g))
117 POINT(55.58852775304245 17.426536064113982) 117 POINT(57.98031067576927 17.854754130800433)
118 POINT(55.58852775304245 17.426536064113982) 118 POINT(57.98031067576927 17.854754130800433)
119 POINT(2 2) 119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid;
fid Area(g) fid Area(g)
......
...@@ -1150,8 +1150,8 @@ int Gis_polygon::centroid_xy(double *x, double *y) const ...@@ -1150,8 +1150,8 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
uint32 n_points, org_n_points; uint32 n_points, org_n_points;
double prev_x, prev_y; double prev_x, prev_y;
double cur_area= 0; double cur_area= 0;
double cur_cx= 0; double cur_cx= 0, cur_cy= 0;
double cur_cy= 0; double sum_cx= 0, sum_cy= 0;
if (no_data(data, 4)) if (no_data(data, 4))
return 1; return 1;
...@@ -1165,17 +1165,32 @@ int Gis_polygon::centroid_xy(double *x, double *y) const ...@@ -1165,17 +1165,32 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
while (--n_points) // One point is already read while (--n_points) // One point is already read
{ {
double tmp_x, tmp_y; double tmp_x, tmp_y;
double loc_area;
get_point(&tmp_x, &tmp_y, data); get_point(&tmp_x, &tmp_y, data);
data+= POINT_DATA_SIZE; 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_cx+= tmp_x;
cur_cy+= tmp_y; 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_x= tmp_x;
prev_y= tmp_y; prev_y= tmp_y;
} }
cur_area= fabs(cur_area) / 2;
cur_cx= cur_cx / (org_n_points - 1); if (fabs(cur_area) > 1e-10)
cur_cy= cur_cy / (org_n_points - 1); {
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) if (!first_loop)
{ {
......
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