From: drh Date: Mon, 8 Oct 2018 18:55:56 +0000 (+0000) Subject: Replace the new geopoly_reverse() function with geopoly_ccw(). The X-Git-Tag: version-3.26.0~96 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5f8cb730afa1017e1ac1af53886027a6a3d98e4e;p=thirdparty%2Fsqlite.git Replace the new geopoly_reverse() function with geopoly_ccw(). The geopoly_ccw() function only reverses the vertex order if doing so is necessary to get the correct right-hand winding rule on the polygon. FossilOrigin-Name: 075066944b13b18d339ccf87ae16f0b91bf00f40bd70f71c6beba6aa6c43f0b6 --- diff --git a/ext/rtree/geopoly.c b/ext/rtree/geopoly.c index c3f3478b5c..be582a3e1b 100644 --- a/ext/rtree/geopoly.c +++ b/ext/rtree/geopoly.c @@ -464,6 +464,27 @@ static void geopolyXformFunc( } } +/* +** Compute the area enclosed by the polygon. +** +** This routine can also be used to detect polygons that rotate in +** the wrong direction. Polygons are suppose to be counter-clockwise (CCW). +** This routine returns a negative value for clockwise (CW) polygons. +*/ +static double geopolyArea(GeoPoly *p){ + double rArea = 0.0; + int ii; + for(ii=0; iinVertex-1; ii++){ + rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ + * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ + * 0.5; + } + rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ + * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ + * 0.5; + return rArea; +} + /* ** Implementation of the geopoly_area(X) function. ** @@ -479,44 +500,41 @@ static void geopolyAreaFunc( ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); if( p ){ - double rArea = 0.0; - int ii; - for(ii=0; iinVertex-1; ii++){ - rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ - * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ - * 0.5; - } - rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ - * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ - * 0.5; - sqlite3_result_double(context, rArea); + sqlite3_result_double(context, geopolyArea(p)); sqlite3_free(p); } } /* -** Implementation of the geopoly_reverse(X) function. +** Implementation of the geopoly_ccw(X) function. +** +** If the rotation of polygon X is clockwise (incorrect) instead of +** counter-clockwise (the correct winding order according to RFC7946) +** then reverse the order of the vertexes in polygon X. ** -** Reverse the order of the vertexes in polygon X. This can be used -** to convert an historical polygon that uses a clockwise rotation into -** a well-formed GeoJSON polygon that uses counter-clockwise rotation. +** In other words, this routine returns a CCW polygon regardless of the +** winding order of its input. +** +** Use this routine to sanitize historical inputs that that sometimes +** contain polygons that wind in the wrong direction. */ -static void geopolyReverseFunc( +static void geopolyCcwFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); if( p ){ - int ii, jj; - for(ii=2, jj=p->nVertex*2 - 4; iia[ii]; - p->a[ii] = p->a[jj]; - p->a[jj] = t; - t = p->a[ii+1]; - p->a[ii+1] = p->a[jj+1]; - p->a[jj+1] = t; - + if( geopolyArea(p)<0.0 ){ + int ii, jj; + for(ii=2, jj=p->nVertex*2 - 4; iia[ii]; + p->a[ii] = p->a[jj]; + p->a[jj] = t; + t = p->a[ii+1]; + p->a[ii+1] = p->a[jj+1]; + p->a[jj+1] = t; + } } sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); @@ -1751,7 +1769,7 @@ static int sqlite3_geopoly_init(sqlite3 *db){ { geopolyBBoxFunc, 1, 1, "geopoly_bbox" }, { geopolyXformFunc, 7, 1, "geopoly_xform" }, { geopolyRegularFunc, 4, 1, "geopoly_regular" }, - { geopolyReverseFunc, 1, 1, "geopoly_reverse" }, + { geopolyCcwFunc, 1, 1, "geopoly_ccw" }, }; static const struct { void (*xStep)(sqlite3_context*,int,sqlite3_value**); diff --git a/manifest b/manifest index 7a838f249e..bc450e6e5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sgeopoly_reverse()\sfunction\sto\sthe\sGeoPoly\sextension. -D 2018-10-08T12:58:59.969 +C Replace\sthe\snew\sgeopoly_reverse()\sfunction\swith\sgeopoly_ccw().\s\sThe\ngeopoly_ccw()\sfunction\sonly\sreverses\sthe\svertex\sorder\sif\sdoing\sso\sis\snecessary\nto\sget\sthe\scorrect\sright-hand\swinding\srule\son\sthe\spolygon. +D 2018-10-08T18:55:56.767 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 01e95208a78b57d056131382c493c963518f36da4c42b12a97eb324401b3a334 @@ -361,7 +361,7 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782 F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/geopoly.c 9d8411b2bcaab719f65acc8a84d16200d5139ac634787df546c31bf9972b34e6 +F ext/rtree/geopoly.c 2464b3325fcc2878ed08458efeb995f830f4eef28bbf3da9757c4bd95e6f9549 F ext/rtree/rtree.c 6cc2e673cf1e9ea1619f13ab990f12389dfb951b131acbc2fbe164cee8992a20 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test 309afc04d4287542b2cd74f933296832cc681c7b014d9405cb329b62053a5349 @@ -1771,7 +1771,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aac8f1dff0728c629b5cbf30369ee91c5862a707ede694dc2628d1d4f5a6c202 -R 6c483dda78db6c9ea6a6a082c4feae71 +P 690dd18a5768c5a8cdfa92d5b01901c1a7b1fb6ebb90399f56a3112e41609f92 +R 35a6105ea46a39f4869622077b954203 U drh -Z f525bca01c12c5943b4f7c604400e173 +Z 59baf7542a91be0562e1f0570ed59fd4 diff --git a/manifest.uuid b/manifest.uuid index b8eda6748b..b661feba37 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -690dd18a5768c5a8cdfa92d5b01901c1a7b1fb6ebb90399f56a3112e41609f92 \ No newline at end of file +075066944b13b18d339ccf87ae16f0b91bf00f40bd70f71c6beba6aa6c43f0b6 \ No newline at end of file