return 0;
}
-/* Forward declaration */
-static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2);
-
/*
-** SQL function: geopoly_within(P,X,Y) -- 3-argument form
+** SQL function: geopoly_contains_point(P,X,Y)
**
** Return +2 if point X,Y is within polygon P.
** Return +1 if point X,Y is on the polygon boundary.
** Return 0 if point X,Y is outside the polygon
-**
-** SQL function: geopoly_within(P1,P2) -- 2-argument form
+*/
+static void geopolyContainsPointFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
+ double x0 = sqlite3_value_double(argv[1]);
+ double y0 = sqlite3_value_double(argv[2]);
+ int v = 0;
+ int cnt = 0;
+ int ii;
+ if( p1==0 ) return;
+ for(ii=0; ii<p1->nVertex-1; ii++){
+ v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
+ p1->a[ii*2+2],p1->a[ii*2+3]);
+ if( v==2 ) break;
+ cnt += v;
+ }
+ if( v!=2 ){
+ v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
+ p1->a[0],p1->a[1]);
+ }
+ if( v==2 ){
+ sqlite3_result_int(context, 1);
+ }else if( ((v+cnt)&1)==0 ){
+ sqlite3_result_int(context, 0);
+ }else{
+ sqlite3_result_int(context, 2);
+ }
+ sqlite3_free(p1);
+}
+
+/* Forward declaration */
+static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2);
+
+/*
+** SQL function: geopoly_within(P1,P2)
**
** Return +2 if P1 and P2 are the same polygon
** Return +1 if P2 is contained within P1
sqlite3_value **argv
){
GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
- if( p1==0 ) return;
- if( argc==3 ){
- double x0 = sqlite3_value_double(argv[1]);
- double y0 = sqlite3_value_double(argv[2]);
- int v = 0;
- int cnt = 0;
- int ii;
- for(ii=0; ii<p1->nVertex-1; ii++){
- v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
- p1->a[ii*2+2],p1->a[ii*2+3]);
- if( v==2 ) break;
- cnt += v;
- }
- if( v!=2 ){
- v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
- p1->a[0],p1->a[1]);
- }
- if( v==2 ){
- sqlite3_result_int(context, 1);
- }else if( ((v+cnt)&1)==0 ){
- sqlite3_result_int(context, 0);
+ GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
+ if( p1 && p2 ){
+ int x = geopolyOverlap(p1, p2);
+ if( x<0 ){
+ sqlite3_result_error_nomem(context);
}else{
- sqlite3_result_int(context, 2);
- }
- }else{
- assert( argc==2 );
- GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
- if( p2 ){
- int x = geopolyOverlap(p1, p2);
- if( x<0 ){
- sqlite3_result_error_nomem(context);
- }else{
- sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0);
- }
- sqlite3_free(p2);
+ sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0);
}
}
sqlite3_free(p1);
+ sqlite3_free(p2);
}
/* Objects used by the overlap algorihm. */
*ppArg = 0;
return SQLITE_INDEX_CONSTRAINT_FUNCTION;
}
- if( nArg==2 && sqlite3_stricmp(zName, "geopoly_within")==0 ){
+ if( sqlite3_stricmp(zName, "geopoly_within")==0 ){
*pxFunc = geopolyWithinFunc;
*ppArg = 0;
return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
int nArg;
const char *zName;
} aFunc[] = {
- { geopolyAreaFunc, 1, "geopoly_area" },
- { geopolyBlobFunc, 1, "geopoly_blob" },
- { geopolyJsonFunc, 1, "geopoly_json" },
- { geopolySvgFunc, -1, "geopoly_svg" },
- { geopolyWithinFunc, 2, "geopoly_within" },
- { geopolyWithinFunc, 3, "geopoly_within" },
- { geopolyOverlapFunc, 2, "geopoly_overlap" },
- { geopolyDebugFunc, 1, "geopoly_debug" },
- { geopolyBBoxFunc, 1, "geopoly_bbox" },
- { geopolyXformFunc, 7, "geopoly_xform" },
+ { geopolyAreaFunc, 1, "geopoly_area" },
+ { geopolyBlobFunc, 1, "geopoly_blob" },
+ { geopolyJsonFunc, 1, "geopoly_json" },
+ { geopolySvgFunc, -1, "geopoly_svg" },
+ { geopolyWithinFunc, 2, "geopoly_within" },
+ { geopolyContainsPointFunc, 3, "geopoly_contains_point" },
+ { geopolyOverlapFunc, 2, "geopoly_overlap" },
+ { geopolyDebugFunc, 1, "geopoly_debug" },
+ { geopolyBBoxFunc, 1, "geopoly_bbox" },
+ { geopolyXformFunc, 7, "geopoly_xform" },
};
int i;
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
-C Enhance\sthe\sgeopoly\svirtual\stable\sso\sthat\sit\sdoes\sa\sbetter\sjob\sof\soptimizing\ngeopoly_within()\squeries.
-D 2018-08-25T23:03:27.261
+C Split\sthe\sthree-argument\sversion\sof\sgeopoly_within()\soff\sinto\sa\sseparate\nfunction\snamed\sgeopoly_contains_point().
+D 2018-08-27T15:55:37.720
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in d06f463c5b623a61ac27f5cb8214fca9e53a6704d34d6b8f2124e2b1b293c88f
F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
-F ext/rtree/geopoly.c a265dcbd7131b3bc92e081a17deb9b502c4f5eb8f21084f8e337013b9ff3a44a
+F ext/rtree/geopoly.c 01343c633cf59893abc0797571dbfe50d116a6474743941ba46b09ad085df271
F ext/rtree/rtree.c f3c2f1b5eea75b98d4d3dcdec2ebf2a69c036b53f2f3d196e61bf5016298255f
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test 309afc04d4287542b2cd74f933296832cc681c7b014d9405cb329b62053a5349
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 6eb5d09b7f9d9bf8edbf993dccc2e2f702b95ba96cf68445609feb0ccc3ac0f7
-R 163f1378dd6b33d45a7ba74154a94c1d
+P 1f717385340f295064a7649cfc36ad048573cbacb6faa20f5c6067328c40c745
+R c8bba0eba3c40fb02a7a476491c628b8
U drh
-Z 9fe6062c3d32e76299fd6a57239e260e
+Z dc507345f435c2e520c7c866391dda2f