geopoly.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840
  1. /*
  2. ** 2018-05-25
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. ******************************************************************************
  12. **
  13. ** This file implements an alternative R-Tree virtual table that
  14. ** uses polygons to express the boundaries of 2-dimensional objects.
  15. **
  16. ** This file is #include-ed onto the end of "rtree.c" so that it has
  17. ** access to all of the R-Tree internals.
  18. */
  19. #include <stdlib.h>
  20. /* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */
  21. #ifdef GEOPOLY_ENABLE_DEBUG
  22. static int geo_debug = 0;
  23. # define GEODEBUG(X) if(geo_debug)printf X
  24. #else
  25. # define GEODEBUG(X)
  26. #endif
  27. /* Character class routines */
  28. #ifdef sqlite3Isdigit
  29. /* Use the SQLite core versions if this routine is part of the
  30. ** SQLite amalgamation */
  31. # define safe_isdigit(x) sqlite3Isdigit(x)
  32. # define safe_isalnum(x) sqlite3Isalnum(x)
  33. # define safe_isxdigit(x) sqlite3Isxdigit(x)
  34. #else
  35. /* Use the standard library for separate compilation */
  36. #include <ctype.h> /* amalgamator: keep */
  37. # define safe_isdigit(x) isdigit((unsigned char)(x))
  38. # define safe_isalnum(x) isalnum((unsigned char)(x))
  39. # define safe_isxdigit(x) isxdigit((unsigned char)(x))
  40. #endif
  41. #ifndef JSON_NULL /* The following stuff repeats things found in json1 */
  42. /*
  43. ** Growing our own isspace() routine this way is twice as fast as
  44. ** the library isspace() function.
  45. */
  46. static const char geopolyIsSpace[] = {
  47. 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
  48. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  49. 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  50. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  51. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  52. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  53. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  54. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  55. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  56. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  57. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  58. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  59. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  60. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  61. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  62. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  63. };
  64. #define fast_isspace(x) (geopolyIsSpace[(unsigned char)x])
  65. #endif /* JSON NULL - back to original code */
  66. /* Compiler and version */
  67. #ifndef GCC_VERSION
  68. #if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
  69. # define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
  70. #else
  71. # define GCC_VERSION 0
  72. #endif
  73. #endif
  74. #ifndef MSVC_VERSION
  75. #if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
  76. # define MSVC_VERSION _MSC_VER
  77. #else
  78. # define MSVC_VERSION 0
  79. #endif
  80. #endif
  81. /* Datatype for coordinates
  82. */
  83. typedef float GeoCoord;
  84. /*
  85. ** Internal representation of a polygon.
  86. **
  87. ** The polygon consists of a sequence of vertexes. There is a line
  88. ** segment between each pair of vertexes, and one final segment from
  89. ** the last vertex back to the first. (This differs from the GeoJSON
  90. ** standard in which the final vertex is a repeat of the first.)
  91. **
  92. ** The polygon follows the right-hand rule. The area to the right of
  93. ** each segment is "outside" and the area to the left is "inside".
  94. **
  95. ** The on-disk representation consists of a 4-byte header followed by
  96. ** the values. The 4-byte header is:
  97. **
  98. ** encoding (1 byte) 0=big-endian, 1=little-endian
  99. ** nvertex (3 bytes) Number of vertexes as a big-endian integer
  100. **
  101. ** Enough space is allocated for 4 coordinates, to work around over-zealous
  102. ** warnings coming from some compiler (notably, clang). In reality, the size
  103. ** of each GeoPoly memory allocate is adjusted as necessary so that the
  104. ** GeoPoly.a[] array at the end is the appropriate size.
  105. */
  106. typedef struct GeoPoly GeoPoly;
  107. struct GeoPoly {
  108. int nVertex; /* Number of vertexes */
  109. unsigned char hdr[4]; /* Header for on-disk representation */
  110. GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */
  111. };
  112. /* The size of a memory allocation needed for a GeoPoly object sufficient
  113. ** to hold N coordinate pairs.
  114. */
  115. #define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
  116. /* Macros to access coordinates of a GeoPoly.
  117. ** We have to use these macros, rather than just say p->a[i] in order
  118. ** to silence (incorrect) UBSAN warnings if the array index is too large.
  119. */
  120. #define GeoX(P,I) (((GeoCoord*)(P)->a)[(I)*2])
  121. #define GeoY(P,I) (((GeoCoord*)(P)->a)[(I)*2+1])
  122. /*
  123. ** State of a parse of a GeoJSON input.
  124. */
  125. typedef struct GeoParse GeoParse;
  126. struct GeoParse {
  127. const unsigned char *z; /* Unparsed input */
  128. int nVertex; /* Number of vertexes in a[] */
  129. int nAlloc; /* Space allocated to a[] */
  130. int nErr; /* Number of errors encountered */
  131. GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */
  132. };
  133. /* Do a 4-byte byte swap */
  134. static void geopolySwab32(unsigned char *a){
  135. unsigned char t = a[0];
  136. a[0] = a[3];
  137. a[3] = t;
  138. t = a[1];
  139. a[1] = a[2];
  140. a[2] = t;
  141. }
  142. /* Skip whitespace. Return the next non-whitespace character. */
  143. static char geopolySkipSpace(GeoParse *p){
  144. while( fast_isspace(p->z[0]) ) p->z++;
  145. return p->z[0];
  146. }
  147. /* Parse out a number. Write the value into *pVal if pVal!=0.
  148. ** return non-zero on success and zero if the next token is not a number.
  149. */
  150. static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
  151. char c = geopolySkipSpace(p);
  152. const unsigned char *z = p->z;
  153. int j = 0;
  154. int seenDP = 0;
  155. int seenE = 0;
  156. if( c=='-' ){
  157. j = 1;
  158. c = z[j];
  159. }
  160. if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
  161. for(;; j++){
  162. c = z[j];
  163. if( safe_isdigit(c) ) continue;
  164. if( c=='.' ){
  165. if( z[j-1]=='-' ) return 0;
  166. if( seenDP ) return 0;
  167. seenDP = 1;
  168. continue;
  169. }
  170. if( c=='e' || c=='E' ){
  171. if( z[j-1]<'0' ) return 0;
  172. if( seenE ) return -1;
  173. seenDP = seenE = 1;
  174. c = z[j+1];
  175. if( c=='+' || c=='-' ){
  176. j++;
  177. c = z[j+1];
  178. }
  179. if( c<'0' || c>'9' ) return 0;
  180. continue;
  181. }
  182. break;
  183. }
  184. if( z[j-1]<'0' ) return 0;
  185. if( pVal ){
  186. #ifdef SQLITE_AMALGAMATION
  187. /* The sqlite3AtoF() routine is much much faster than atof(), if it
  188. ** is available */
  189. double r;
  190. (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
  191. *pVal = r;
  192. #else
  193. *pVal = (GeoCoord)atof((const char*)p->z);
  194. #endif
  195. }
  196. p->z += j;
  197. return 1;
  198. }
  199. /*
  200. ** If the input is a well-formed JSON array of coordinates with at least
  201. ** four coordinates and where each coordinate is itself a two-value array,
  202. ** then convert the JSON into a GeoPoly object and return a pointer to
  203. ** that object.
  204. **
  205. ** If any error occurs, return NULL.
  206. */
  207. static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
  208. GeoParse s;
  209. int rc = SQLITE_OK;
  210. memset(&s, 0, sizeof(s));
  211. s.z = z;
  212. if( geopolySkipSpace(&s)=='[' ){
  213. s.z++;
  214. while( geopolySkipSpace(&s)=='[' ){
  215. int ii = 0;
  216. char c;
  217. s.z++;
  218. if( s.nVertex>=s.nAlloc ){
  219. GeoCoord *aNew;
  220. s.nAlloc = s.nAlloc*2 + 16;
  221. aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 );
  222. if( aNew==0 ){
  223. rc = SQLITE_NOMEM;
  224. s.nErr++;
  225. break;
  226. }
  227. s.a = aNew;
  228. }
  229. while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){
  230. ii++;
  231. if( ii==2 ) s.nVertex++;
  232. c = geopolySkipSpace(&s);
  233. s.z++;
  234. if( c==',' ) continue;
  235. if( c==']' && ii>=2 ) break;
  236. s.nErr++;
  237. rc = SQLITE_ERROR;
  238. goto parse_json_err;
  239. }
  240. if( geopolySkipSpace(&s)==',' ){
  241. s.z++;
  242. continue;
  243. }
  244. break;
  245. }
  246. if( geopolySkipSpace(&s)==']'
  247. && s.nVertex>=4
  248. && s.a[0]==s.a[s.nVertex*2-2]
  249. && s.a[1]==s.a[s.nVertex*2-1]
  250. && (s.z++, geopolySkipSpace(&s)==0)
  251. ){
  252. GeoPoly *pOut;
  253. int x = 1;
  254. s.nVertex--; /* Remove the redundant vertex at the end */
  255. pOut = sqlite3_malloc64( GEOPOLY_SZ((sqlite3_int64)s.nVertex) );
  256. x = 1;
  257. if( pOut==0 ) goto parse_json_err;
  258. pOut->nVertex = s.nVertex;
  259. memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
  260. pOut->hdr[0] = *(unsigned char*)&x;
  261. pOut->hdr[1] = (s.nVertex>>16)&0xff;
  262. pOut->hdr[2] = (s.nVertex>>8)&0xff;
  263. pOut->hdr[3] = s.nVertex&0xff;
  264. sqlite3_free(s.a);
  265. if( pRc ) *pRc = SQLITE_OK;
  266. return pOut;
  267. }else{
  268. s.nErr++;
  269. rc = SQLITE_ERROR;
  270. }
  271. }
  272. parse_json_err:
  273. if( pRc ) *pRc = rc;
  274. sqlite3_free(s.a);
  275. return 0;
  276. }
  277. /*
  278. ** Given a function parameter, try to interpret it as a polygon, either
  279. ** in the binary format or JSON text. Compute a GeoPoly object and
  280. ** return a pointer to that object. Or if the input is not a well-formed
  281. ** polygon, put an error message in sqlite3_context and return NULL.
  282. */
  283. static GeoPoly *geopolyFuncParam(
  284. sqlite3_context *pCtx, /* Context for error messages */
  285. sqlite3_value *pVal, /* The value to decode */
  286. int *pRc /* Write error here */
  287. ){
  288. GeoPoly *p = 0;
  289. int nByte;
  290. testcase( pCtx==0 );
  291. if( sqlite3_value_type(pVal)==SQLITE_BLOB
  292. && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord))
  293. ){
  294. const unsigned char *a = sqlite3_value_blob(pVal);
  295. int nVertex;
  296. if( a==0 ){
  297. if( pCtx ) sqlite3_result_error_nomem(pCtx);
  298. return 0;
  299. }
  300. nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
  301. if( (a[0]==0 || a[0]==1)
  302. && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte
  303. ){
  304. p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) );
  305. if( p==0 ){
  306. if( pRc ) *pRc = SQLITE_NOMEM;
  307. if( pCtx ) sqlite3_result_error_nomem(pCtx);
  308. }else{
  309. int x = 1;
  310. p->nVertex = nVertex;
  311. memcpy(p->hdr, a, nByte);
  312. if( a[0] != *(unsigned char*)&x ){
  313. int ii;
  314. for(ii=0; ii<nVertex; ii++){
  315. geopolySwab32((unsigned char*)&GeoX(p,ii));
  316. geopolySwab32((unsigned char*)&GeoY(p,ii));
  317. }
  318. p->hdr[0] ^= 1;
  319. }
  320. }
  321. }
  322. if( pRc ) *pRc = SQLITE_OK;
  323. return p;
  324. }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){
  325. const unsigned char *zJson = sqlite3_value_text(pVal);
  326. if( zJson==0 ){
  327. if( pRc ) *pRc = SQLITE_NOMEM;
  328. return 0;
  329. }
  330. return geopolyParseJson(zJson, pRc);
  331. }else{
  332. if( pRc ) *pRc = SQLITE_ERROR;
  333. return 0;
  334. }
  335. }
  336. /*
  337. ** Implementation of the geopoly_blob(X) function.
  338. **
  339. ** If the input is a well-formed Geopoly BLOB or JSON string
  340. ** then return the BLOB representation of the polygon. Otherwise
  341. ** return NULL.
  342. */
  343. static void geopolyBlobFunc(
  344. sqlite3_context *context,
  345. int argc,
  346. sqlite3_value **argv
  347. ){
  348. GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
  349. (void)argc;
  350. if( p ){
  351. sqlite3_result_blob(context, p->hdr,
  352. 4+8*p->nVertex, SQLITE_TRANSIENT);
  353. sqlite3_free(p);
  354. }
  355. }
  356. /*
  357. ** SQL function: geopoly_json(X)
  358. **
  359. ** Interpret X as a polygon and render it as a JSON array
  360. ** of coordinates. Or, if X is not a valid polygon, return NULL.
  361. */
  362. static void geopolyJsonFunc(
  363. sqlite3_context *context,
  364. int argc,
  365. sqlite3_value **argv
  366. ){
  367. GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
  368. (void)argc;
  369. if( p ){
  370. sqlite3 *db = sqlite3_context_db_handle(context);
  371. sqlite3_str *x = sqlite3_str_new(db);
  372. int i;
  373. sqlite3_str_append(x, "[", 1);
  374. for(i=0; i<p->nVertex; i++){
  375. sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i));
  376. }
  377. sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0));
  378. sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
  379. sqlite3_free(p);
  380. }
  381. }
  382. /*
  383. ** SQL function: geopoly_svg(X, ....)
  384. **
  385. ** Interpret X as a polygon and render it as a SVG <polyline>.
  386. ** Additional arguments are added as attributes to the <polyline>.
  387. */
  388. static void geopolySvgFunc(
  389. sqlite3_context *context,
  390. int argc,
  391. sqlite3_value **argv
  392. ){
  393. GeoPoly *p;
  394. if( argc<1 ) return;
  395. p = geopolyFuncParam(context, argv[0], 0);
  396. if( p ){
  397. sqlite3 *db = sqlite3_context_db_handle(context);
  398. sqlite3_str *x = sqlite3_str_new(db);
  399. int i;
  400. char cSep = '\'';
  401. sqlite3_str_appendf(x, "<polyline points=");
  402. for(i=0; i<p->nVertex; i++){
  403. sqlite3_str_appendf(x, "%c%g,%g", cSep, GeoX(p,i), GeoY(p,i));
  404. cSep = ' ';
  405. }
  406. sqlite3_str_appendf(x, " %g,%g'", GeoX(p,0), GeoY(p,0));
  407. for(i=1; i<argc; i++){
  408. const char *z = (const char*)sqlite3_value_text(argv[i]);
  409. if( z && z[0] ){
  410. sqlite3_str_appendf(x, " %s", z);
  411. }
  412. }
  413. sqlite3_str_appendf(x, "></polyline>");
  414. sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
  415. sqlite3_free(p);
  416. }
  417. }
  418. /*
  419. ** SQL Function: geopoly_xform(poly, A, B, C, D, E, F)
  420. **
  421. ** Transform and/or translate a polygon as follows:
  422. **
  423. ** x1 = A*x0 + B*y0 + E
  424. ** y1 = C*x0 + D*y0 + F
  425. **
  426. ** For a translation:
  427. **
  428. ** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset)
  429. **
  430. ** Rotate by R around the point (0,0):
  431. **
  432. ** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0)
  433. */
  434. static void geopolyXformFunc(
  435. sqlite3_context *context,
  436. int argc,
  437. sqlite3_value **argv
  438. ){
  439. GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
  440. double A = sqlite3_value_double(argv[1]);
  441. double B = sqlite3_value_double(argv[2]);
  442. double C = sqlite3_value_double(argv[3]);
  443. double D = sqlite3_value_double(argv[4]);
  444. double E = sqlite3_value_double(argv[5]);
  445. double F = sqlite3_value_double(argv[6]);
  446. GeoCoord x1, y1, x0, y0;
  447. int ii;
  448. (void)argc;
  449. if( p ){
  450. for(ii=0; ii<p->nVertex; ii++){
  451. x0 = GeoX(p,ii);
  452. y0 = GeoY(p,ii);
  453. x1 = (GeoCoord)(A*x0 + B*y0 + E);
  454. y1 = (GeoCoord)(C*x0 + D*y0 + F);
  455. GeoX(p,ii) = x1;
  456. GeoY(p,ii) = y1;
  457. }
  458. sqlite3_result_blob(context, p->hdr,
  459. 4+8*p->nVertex, SQLITE_TRANSIENT);
  460. sqlite3_free(p);
  461. }
  462. }
  463. /*
  464. ** Compute the area enclosed by the polygon.
  465. **
  466. ** This routine can also be used to detect polygons that rotate in
  467. ** the wrong direction. Polygons are suppose to be counter-clockwise (CCW).
  468. ** This routine returns a negative value for clockwise (CW) polygons.
  469. */
  470. static double geopolyArea(GeoPoly *p){
  471. double rArea = 0.0;
  472. int ii;
  473. for(ii=0; ii<p->nVertex-1; ii++){
  474. rArea += (GeoX(p,ii) - GeoX(p,ii+1)) /* (x0 - x1) */
  475. * (GeoY(p,ii) + GeoY(p,ii+1)) /* (y0 + y1) */
  476. * 0.5;
  477. }
  478. rArea += (GeoX(p,ii) - GeoX(p,0)) /* (xN - x0) */
  479. * (GeoY(p,ii) + GeoY(p,0)) /* (yN + y0) */
  480. * 0.5;
  481. return rArea;
  482. }
  483. /*
  484. ** Implementation of the geopoly_area(X) function.
  485. **
  486. ** If the input is a well-formed Geopoly BLOB then return the area
  487. ** enclosed by the polygon. If the polygon circulates clockwise instead
  488. ** of counterclockwise (as it should) then return the negative of the
  489. ** enclosed area. Otherwise return NULL.
  490. */
  491. static void geopolyAreaFunc(
  492. sqlite3_context *context,
  493. int argc,
  494. sqlite3_value **argv
  495. ){
  496. GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
  497. (void)argc;
  498. if( p ){
  499. sqlite3_result_double(context, geopolyArea(p));
  500. sqlite3_free(p);
  501. }
  502. }
  503. /*
  504. ** Implementation of the geopoly_ccw(X) function.
  505. **
  506. ** If the rotation of polygon X is clockwise (incorrect) instead of
  507. ** counter-clockwise (the correct winding order according to RFC7946)
  508. ** then reverse the order of the vertexes in polygon X.
  509. **
  510. ** In other words, this routine returns a CCW polygon regardless of the
  511. ** winding order of its input.
  512. **
  513. ** Use this routine to sanitize historical inputs that that sometimes
  514. ** contain polygons that wind in the wrong direction.
  515. */
  516. static void geopolyCcwFunc(
  517. sqlite3_context *context,
  518. int argc,
  519. sqlite3_value **argv
  520. ){
  521. GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
  522. (void)argc;
  523. if( p ){
  524. if( geopolyArea(p)<0.0 ){
  525. int ii, jj;
  526. for(ii=1, jj=p->nVertex-1; ii<jj; ii++, jj--){
  527. GeoCoord t = GeoX(p,ii);
  528. GeoX(p,ii) = GeoX(p,jj);
  529. GeoX(p,jj) = t;
  530. t = GeoY(p,ii);
  531. GeoY(p,ii) = GeoY(p,jj);
  532. GeoY(p,jj) = t;
  533. }
  534. }
  535. sqlite3_result_blob(context, p->hdr,
  536. 4+8*p->nVertex, SQLITE_TRANSIENT);
  537. sqlite3_free(p);
  538. }
  539. }
  540. #define GEOPOLY_PI 3.1415926535897932385
  541. /* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
  542. */
  543. static double geopolySine(double r){
  544. assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
  545. if( r>=1.5*GEOPOLY_PI ){
  546. r -= 2.0*GEOPOLY_PI;
  547. }
  548. if( r>=0.5*GEOPOLY_PI ){
  549. return -geopolySine(r-GEOPOLY_PI);
  550. }else{
  551. double r2 = r*r;
  552. double r3 = r2*r;
  553. double r5 = r3*r2;
  554. return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
  555. }
  556. }
  557. /*
  558. ** Function: geopoly_regular(X,Y,R,N)
  559. **
  560. ** Construct a simple, convex, regular polygon centered at X, Y
  561. ** with circumradius R and with N sides.
  562. */
  563. static void geopolyRegularFunc(
  564. sqlite3_context *context,
  565. int argc,
  566. sqlite3_value **argv
  567. ){
  568. double x = sqlite3_value_double(argv[0]);
  569. double y = sqlite3_value_double(argv[1]);
  570. double r = sqlite3_value_double(argv[2]);
  571. int n = sqlite3_value_int(argv[3]);
  572. int i;
  573. GeoPoly *p;
  574. (void)argc;
  575. if( n<3 || r<=0.0 ) return;
  576. if( n>1000 ) n = 1000;
  577. p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
  578. if( p==0 ){
  579. sqlite3_result_error_nomem(context);
  580. return;
  581. }
  582. i = 1;
  583. p->hdr[0] = *(unsigned char*)&i;
  584. p->hdr[1] = 0;
  585. p->hdr[2] = (n>>8)&0xff;
  586. p->hdr[3] = n&0xff;
  587. for(i=0; i<n; i++){
  588. double rAngle = 2.0*GEOPOLY_PI*i/n;
  589. GeoX(p,i) = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
  590. GeoY(p,i) = y + r*geopolySine(rAngle);
  591. }
  592. sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
  593. sqlite3_free(p);
  594. }
  595. /*
  596. ** If pPoly is a polygon, compute its bounding box. Then:
  597. **
  598. ** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
  599. ** (2) otherwise, compute a GeoPoly for the bounding box and return the
  600. ** new GeoPoly
  601. **
  602. ** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from
  603. ** the bounding box in aCoord and return a pointer to that GeoPoly.
  604. */
  605. static GeoPoly *geopolyBBox(
  606. sqlite3_context *context, /* For recording the error */
  607. sqlite3_value *pPoly, /* The polygon */
  608. RtreeCoord *aCoord, /* Results here */
  609. int *pRc /* Error code here */
  610. ){
  611. GeoPoly *pOut = 0;
  612. GeoPoly *p;
  613. float mnX, mxX, mnY, mxY;
  614. if( pPoly==0 && aCoord!=0 ){
  615. p = 0;
  616. mnX = aCoord[0].f;
  617. mxX = aCoord[1].f;
  618. mnY = aCoord[2].f;
  619. mxY = aCoord[3].f;
  620. goto geopolyBboxFill;
  621. }else{
  622. p = geopolyFuncParam(context, pPoly, pRc);
  623. }
  624. if( p ){
  625. int ii;
  626. mnX = mxX = GeoX(p,0);
  627. mnY = mxY = GeoY(p,0);
  628. for(ii=1; ii<p->nVertex; ii++){
  629. double r = GeoX(p,ii);
  630. if( r<mnX ) mnX = (float)r;
  631. else if( r>mxX ) mxX = (float)r;
  632. r = GeoY(p,ii);
  633. if( r<mnY ) mnY = (float)r;
  634. else if( r>mxY ) mxY = (float)r;
  635. }
  636. if( pRc ) *pRc = SQLITE_OK;
  637. if( aCoord==0 ){
  638. geopolyBboxFill:
  639. pOut = sqlite3_realloc64(p, GEOPOLY_SZ(4));
  640. if( pOut==0 ){
  641. sqlite3_free(p);
  642. if( context ) sqlite3_result_error_nomem(context);
  643. if( pRc ) *pRc = SQLITE_NOMEM;
  644. return 0;
  645. }
  646. pOut->nVertex = 4;
  647. ii = 1;
  648. pOut->hdr[0] = *(unsigned char*)&ii;
  649. pOut->hdr[1] = 0;
  650. pOut->hdr[2] = 0;
  651. pOut->hdr[3] = 4;
  652. GeoX(pOut,0) = mnX;
  653. GeoY(pOut,0) = mnY;
  654. GeoX(pOut,1) = mxX;
  655. GeoY(pOut,1) = mnY;
  656. GeoX(pOut,2) = mxX;
  657. GeoY(pOut,2) = mxY;
  658. GeoX(pOut,3) = mnX;
  659. GeoY(pOut,3) = mxY;
  660. }else{
  661. sqlite3_free(p);
  662. aCoord[0].f = mnX;
  663. aCoord[1].f = mxX;
  664. aCoord[2].f = mnY;
  665. aCoord[3].f = mxY;
  666. }
  667. }else if( aCoord ){
  668. memset(aCoord, 0, sizeof(RtreeCoord)*4);
  669. }
  670. return pOut;
  671. }
  672. /*
  673. ** Implementation of the geopoly_bbox(X) SQL function.
  674. */
  675. static void geopolyBBoxFunc(
  676. sqlite3_context *context,
  677. int argc,
  678. sqlite3_value **argv
  679. ){
  680. GeoPoly *p = geopolyBBox(context, argv[0], 0, 0);
  681. (void)argc;
  682. if( p ){
  683. sqlite3_result_blob(context, p->hdr,
  684. 4+8*p->nVertex, SQLITE_TRANSIENT);
  685. sqlite3_free(p);
  686. }
  687. }
  688. /*
  689. ** State vector for the geopoly_group_bbox() aggregate function.
  690. */
  691. typedef struct GeoBBox GeoBBox;
  692. struct GeoBBox {
  693. int isInit;
  694. RtreeCoord a[4];
  695. };
  696. /*
  697. ** Implementation of the geopoly_group_bbox(X) aggregate SQL function.
  698. */
  699. static void geopolyBBoxStep(
  700. sqlite3_context *context,
  701. int argc,
  702. sqlite3_value **argv
  703. ){
  704. RtreeCoord a[4];
  705. int rc = SQLITE_OK;
  706. (void)argc;
  707. (void)geopolyBBox(context, argv[0], a, &rc);
  708. if( rc==SQLITE_OK ){
  709. GeoBBox *pBBox;
  710. pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox));
  711. if( pBBox==0 ) return;
  712. if( pBBox->isInit==0 ){
  713. pBBox->isInit = 1;
  714. memcpy(pBBox->a, a, sizeof(RtreeCoord)*4);
  715. }else{
  716. if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0];
  717. if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1];
  718. if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2];
  719. if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3];
  720. }
  721. }
  722. }
  723. static void geopolyBBoxFinal(
  724. sqlite3_context *context
  725. ){
  726. GeoPoly *p;
  727. GeoBBox *pBBox;
  728. pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0);
  729. if( pBBox==0 ) return;
  730. p = geopolyBBox(context, 0, pBBox->a, 0);
  731. if( p ){
  732. sqlite3_result_blob(context, p->hdr,
  733. 4+8*p->nVertex, SQLITE_TRANSIENT);
  734. sqlite3_free(p);
  735. }
  736. }
  737. /*
  738. ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2).
  739. ** Returns:
  740. **
  741. ** +2 x0,y0 is on the line segement
  742. **
  743. ** +1 x0,y0 is beneath line segment
  744. **
  745. ** 0 x0,y0 is not on or beneath the line segment or the line segment
  746. ** is vertical and x0,y0 is not on the line segment
  747. **
  748. ** The left-most coordinate min(x1,x2) is not considered to be part of
  749. ** the line segment for the purposes of this analysis.
  750. */
  751. static int pointBeneathLine(
  752. double x0, double y0,
  753. double x1, double y1,
  754. double x2, double y2
  755. ){
  756. double y;
  757. if( x0==x1 && y0==y1 ) return 2;
  758. if( x1<x2 ){
  759. if( x0<=x1 || x0>x2 ) return 0;
  760. }else if( x1>x2 ){
  761. if( x0<=x2 || x0>x1 ) return 0;
  762. }else{
  763. /* Vertical line segment */
  764. if( x0!=x1 ) return 0;
  765. if( y0<y1 && y0<y2 ) return 0;
  766. if( y0>y1 && y0>y2 ) return 0;
  767. return 2;
  768. }
  769. y = y1 + (y2-y1)*(x0-x1)/(x2-x1);
  770. if( y0==y ) return 2;
  771. if( y0<y ) return 1;
  772. return 0;
  773. }
  774. /*
  775. ** SQL function: geopoly_contains_point(P,X,Y)
  776. **
  777. ** Return +2 if point X,Y is within polygon P.
  778. ** Return +1 if point X,Y is on the polygon boundary.
  779. ** Return 0 if point X,Y is outside the polygon
  780. */
  781. static void geopolyContainsPointFunc(
  782. sqlite3_context *context,
  783. int argc,
  784. sqlite3_value **argv
  785. ){
  786. GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
  787. double x0 = sqlite3_value_double(argv[1]);
  788. double y0 = sqlite3_value_double(argv[2]);
  789. int v = 0;
  790. int cnt = 0;
  791. int ii;
  792. (void)argc;
  793. if( p1==0 ) return;
  794. for(ii=0; ii<p1->nVertex-1; ii++){
  795. v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
  796. GeoX(p1,ii+1),GeoY(p1,ii+1));
  797. if( v==2 ) break;
  798. cnt += v;
  799. }
  800. if( v!=2 ){
  801. v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
  802. GeoX(p1,0), GeoY(p1,0));
  803. }
  804. if( v==2 ){
  805. sqlite3_result_int(context, 1);
  806. }else if( ((v+cnt)&1)==0 ){
  807. sqlite3_result_int(context, 0);
  808. }else{
  809. sqlite3_result_int(context, 2);
  810. }
  811. sqlite3_free(p1);
  812. }
  813. /* Forward declaration */
  814. static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2);
  815. /*
  816. ** SQL function: geopoly_within(P1,P2)
  817. **
  818. ** Return +2 if P1 and P2 are the same polygon
  819. ** Return +1 if P2 is contained within P1
  820. ** Return 0 if any part of P2 is on the outside of P1
  821. **
  822. */
  823. static void geopolyWithinFunc(
  824. sqlite3_context *context,
  825. int argc,
  826. sqlite3_value **argv
  827. ){
  828. GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
  829. GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
  830. (void)argc;
  831. if( p1 && p2 ){
  832. int x = geopolyOverlap(p1, p2);
  833. if( x<0 ){
  834. sqlite3_result_error_nomem(context);
  835. }else{
  836. sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0);
  837. }
  838. }
  839. sqlite3_free(p1);
  840. sqlite3_free(p2);
  841. }
  842. /* Objects used by the overlap algorihm. */
  843. typedef struct GeoEvent GeoEvent;
  844. typedef struct GeoSegment GeoSegment;
  845. typedef struct GeoOverlap GeoOverlap;
  846. struct GeoEvent {
  847. double x; /* X coordinate at which event occurs */
  848. int eType; /* 0 for ADD, 1 for REMOVE */
  849. GeoSegment *pSeg; /* The segment to be added or removed */
  850. GeoEvent *pNext; /* Next event in the sorted list */
  851. };
  852. struct GeoSegment {
  853. double C, B; /* y = C*x + B */
  854. double y; /* Current y value */
  855. float y0; /* Initial y value */
  856. unsigned char side; /* 1 for p1, 2 for p2 */
  857. unsigned int idx; /* Which segment within the side */
  858. GeoSegment *pNext; /* Next segment in a list sorted by y */
  859. };
  860. struct GeoOverlap {
  861. GeoEvent *aEvent; /* Array of all events */
  862. GeoSegment *aSegment; /* Array of all segments */
  863. int nEvent; /* Number of events */
  864. int nSegment; /* Number of segments */
  865. };
  866. /*
  867. ** Add a single segment and its associated events.
  868. */
  869. static void geopolyAddOneSegment(
  870. GeoOverlap *p,
  871. GeoCoord x0,
  872. GeoCoord y0,
  873. GeoCoord x1,
  874. GeoCoord y1,
  875. unsigned char side,
  876. unsigned int idx
  877. ){
  878. GeoSegment *pSeg;
  879. GeoEvent *pEvent;
  880. if( x0==x1 ) return; /* Ignore vertical segments */
  881. if( x0>x1 ){
  882. GeoCoord t = x0;
  883. x0 = x1;
  884. x1 = t;
  885. t = y0;
  886. y0 = y1;
  887. y1 = t;
  888. }
  889. pSeg = p->aSegment + p->nSegment;
  890. p->nSegment++;
  891. pSeg->C = (y1-y0)/(x1-x0);
  892. pSeg->B = y1 - x1*pSeg->C;
  893. pSeg->y0 = y0;
  894. pSeg->side = side;
  895. pSeg->idx = idx;
  896. pEvent = p->aEvent + p->nEvent;
  897. p->nEvent++;
  898. pEvent->x = x0;
  899. pEvent->eType = 0;
  900. pEvent->pSeg = pSeg;
  901. pEvent = p->aEvent + p->nEvent;
  902. p->nEvent++;
  903. pEvent->x = x1;
  904. pEvent->eType = 1;
  905. pEvent->pSeg = pSeg;
  906. }
  907. /*
  908. ** Insert all segments and events for polygon pPoly.
  909. */
  910. static void geopolyAddSegments(
  911. GeoOverlap *p, /* Add segments to this Overlap object */
  912. GeoPoly *pPoly, /* Take all segments from this polygon */
  913. unsigned char side /* The side of pPoly */
  914. ){
  915. unsigned int i;
  916. GeoCoord *x;
  917. for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
  918. x = &GeoX(pPoly,i);
  919. geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
  920. }
  921. x = &GeoX(pPoly,i);
  922. geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
  923. }
  924. /*
  925. ** Merge two lists of sorted events by X coordinate
  926. */
  927. static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){
  928. GeoEvent head, *pLast;
  929. head.pNext = 0;
  930. pLast = &head;
  931. while( pRight && pLeft ){
  932. if( pRight->x <= pLeft->x ){
  933. pLast->pNext = pRight;
  934. pLast = pRight;
  935. pRight = pRight->pNext;
  936. }else{
  937. pLast->pNext = pLeft;
  938. pLast = pLeft;
  939. pLeft = pLeft->pNext;
  940. }
  941. }
  942. pLast->pNext = pRight ? pRight : pLeft;
  943. return head.pNext;
  944. }
  945. /*
  946. ** Sort an array of nEvent event objects into a list.
  947. */
  948. static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){
  949. int mx = 0;
  950. int i, j;
  951. GeoEvent *p;
  952. GeoEvent *a[50];
  953. for(i=0; i<nEvent; i++){
  954. p = &aEvent[i];
  955. p->pNext = 0;
  956. for(j=0; j<mx && a[j]; j++){
  957. p = geopolyEventMerge(a[j], p);
  958. a[j] = 0;
  959. }
  960. a[j] = p;
  961. if( j>=mx ) mx = j+1;
  962. }
  963. p = 0;
  964. for(i=0; i<mx; i++){
  965. p = geopolyEventMerge(a[i], p);
  966. }
  967. return p;
  968. }
  969. /*
  970. ** Merge two lists of sorted segments by Y, and then by C.
  971. */
  972. static GeoSegment *geopolySegmentMerge(GeoSegment *pLeft, GeoSegment *pRight){
  973. GeoSegment head, *pLast;
  974. head.pNext = 0;
  975. pLast = &head;
  976. while( pRight && pLeft ){
  977. double r = pRight->y - pLeft->y;
  978. if( r==0.0 ) r = pRight->C - pLeft->C;
  979. if( r<0.0 ){
  980. pLast->pNext = pRight;
  981. pLast = pRight;
  982. pRight = pRight->pNext;
  983. }else{
  984. pLast->pNext = pLeft;
  985. pLast = pLeft;
  986. pLeft = pLeft->pNext;
  987. }
  988. }
  989. pLast->pNext = pRight ? pRight : pLeft;
  990. return head.pNext;
  991. }
  992. /*
  993. ** Sort a list of GeoSegments in order of increasing Y and in the event of
  994. ** a tie, increasing C (slope).
  995. */
  996. static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){
  997. int mx = 0;
  998. int i;
  999. GeoSegment *p;
  1000. GeoSegment *a[50];
  1001. while( pList ){
  1002. p = pList;
  1003. pList = pList->pNext;
  1004. p->pNext = 0;
  1005. for(i=0; i<mx && a[i]; i++){
  1006. p = geopolySegmentMerge(a[i], p);
  1007. a[i] = 0;
  1008. }
  1009. a[i] = p;
  1010. if( i>=mx ) mx = i+1;
  1011. }
  1012. p = 0;
  1013. for(i=0; i<mx; i++){
  1014. p = geopolySegmentMerge(a[i], p);
  1015. }
  1016. return p;
  1017. }
  1018. /*
  1019. ** Determine the overlap between two polygons
  1020. */
  1021. static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
  1022. sqlite3_int64 nVertex = p1->nVertex + p2->nVertex + 2;
  1023. GeoOverlap *p;
  1024. sqlite3_int64 nByte;
  1025. GeoEvent *pThisEvent;
  1026. double rX;
  1027. int rc = 0;
  1028. int needSort = 0;
  1029. GeoSegment *pActive = 0;
  1030. GeoSegment *pSeg;
  1031. unsigned char aOverlap[4];
  1032. nByte = sizeof(GeoEvent)*nVertex*2
  1033. + sizeof(GeoSegment)*nVertex
  1034. + sizeof(GeoOverlap);
  1035. p = sqlite3_malloc64( nByte );
  1036. if( p==0 ) return -1;
  1037. p->aEvent = (GeoEvent*)&p[1];
  1038. p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
  1039. p->nEvent = p->nSegment = 0;
  1040. geopolyAddSegments(p, p1, 1);
  1041. geopolyAddSegments(p, p2, 2);
  1042. pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent);
  1043. rX = pThisEvent && pThisEvent->x==0.0 ? -1.0 : 0.0;
  1044. memset(aOverlap, 0, sizeof(aOverlap));
  1045. while( pThisEvent ){
  1046. if( pThisEvent->x!=rX ){
  1047. GeoSegment *pPrev = 0;
  1048. int iMask = 0;
  1049. GEODEBUG(("Distinct X: %g\n", pThisEvent->x));
  1050. rX = pThisEvent->x;
  1051. if( needSort ){
  1052. GEODEBUG(("SORT\n"));
  1053. pActive = geopolySortSegmentsByYAndC(pActive);
  1054. needSort = 0;
  1055. }
  1056. for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
  1057. if( pPrev ){
  1058. if( pPrev->y!=pSeg->y ){
  1059. GEODEBUG(("MASK: %d\n", iMask));
  1060. aOverlap[iMask] = 1;
  1061. }
  1062. }
  1063. iMask ^= pSeg->side;
  1064. pPrev = pSeg;
  1065. }
  1066. pPrev = 0;
  1067. for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
  1068. double y = pSeg->C*rX + pSeg->B;
  1069. GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y));
  1070. pSeg->y = y;
  1071. if( pPrev ){
  1072. if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){
  1073. rc = 1;
  1074. GEODEBUG(("Crossing: %d.%d and %d.%d\n",
  1075. pPrev->side, pPrev->idx,
  1076. pSeg->side, pSeg->idx));
  1077. goto geopolyOverlapDone;
  1078. }else if( pPrev->y!=pSeg->y ){
  1079. GEODEBUG(("MASK: %d\n", iMask));
  1080. aOverlap[iMask] = 1;
  1081. }
  1082. }
  1083. iMask ^= pSeg->side;
  1084. pPrev = pSeg;
  1085. }
  1086. }
  1087. GEODEBUG(("%s %d.%d C=%g B=%g\n",
  1088. pThisEvent->eType ? "RM " : "ADD",
  1089. pThisEvent->pSeg->side, pThisEvent->pSeg->idx,
  1090. pThisEvent->pSeg->C,
  1091. pThisEvent->pSeg->B));
  1092. if( pThisEvent->eType==0 ){
  1093. /* Add a segment */
  1094. pSeg = pThisEvent->pSeg;
  1095. pSeg->y = pSeg->y0;
  1096. pSeg->pNext = pActive;
  1097. pActive = pSeg;
  1098. needSort = 1;
  1099. }else{
  1100. /* Remove a segment */
  1101. if( pActive==pThisEvent->pSeg ){
  1102. pActive = ALWAYS(pActive) ? pActive->pNext : 0;
  1103. }else{
  1104. for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
  1105. if( pSeg->pNext==pThisEvent->pSeg ){
  1106. pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0;
  1107. break;
  1108. }
  1109. }
  1110. }
  1111. }
  1112. pThisEvent = pThisEvent->pNext;
  1113. }
  1114. if( aOverlap[3]==0 ){
  1115. rc = 0;
  1116. }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){
  1117. rc = 3;
  1118. }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){
  1119. rc = 2;
  1120. }else if( aOverlap[1]==0 && aOverlap[2]==0 ){
  1121. rc = 4;
  1122. }else{
  1123. rc = 1;
  1124. }
  1125. geopolyOverlapDone:
  1126. sqlite3_free(p);
  1127. return rc;
  1128. }
  1129. /*
  1130. ** SQL function: geopoly_overlap(P1,P2)
  1131. **
  1132. ** Determine whether or not P1 and P2 overlap. Return value:
  1133. **
  1134. ** 0 The two polygons are disjoint
  1135. ** 1 They overlap
  1136. ** 2 P1 is completely contained within P2
  1137. ** 3 P2 is completely contained within P1
  1138. ** 4 P1 and P2 are the same polygon
  1139. ** NULL Either P1 or P2 or both are not valid polygons
  1140. */
  1141. static void geopolyOverlapFunc(
  1142. sqlite3_context *context,
  1143. int argc,
  1144. sqlite3_value **argv
  1145. ){
  1146. GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
  1147. GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
  1148. (void)argc;
  1149. if( p1 && p2 ){
  1150. int x = geopolyOverlap(p1, p2);
  1151. if( x<0 ){
  1152. sqlite3_result_error_nomem(context);
  1153. }else{
  1154. sqlite3_result_int(context, x);
  1155. }
  1156. }
  1157. sqlite3_free(p1);
  1158. sqlite3_free(p2);
  1159. }
  1160. /*
  1161. ** Enable or disable debugging output
  1162. */
  1163. static void geopolyDebugFunc(
  1164. sqlite3_context *context,
  1165. int argc,
  1166. sqlite3_value **argv
  1167. ){
  1168. (void)context;
  1169. (void)argc;
  1170. #ifdef GEOPOLY_ENABLE_DEBUG
  1171. geo_debug = sqlite3_value_int(argv[0]);
  1172. #else
  1173. (void)argv;
  1174. #endif
  1175. }
  1176. /*
  1177. ** This function is the implementation of both the xConnect and xCreate
  1178. ** methods of the geopoly virtual table.
  1179. **
  1180. ** argv[0] -> module name
  1181. ** argv[1] -> database name
  1182. ** argv[2] -> table name
  1183. ** argv[...] -> column names...
  1184. */
  1185. static int geopolyInit(
  1186. sqlite3 *db, /* Database connection */
  1187. void *pAux, /* One of the RTREE_COORD_* constants */
  1188. int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */
  1189. sqlite3_vtab **ppVtab, /* OUT: New virtual table */
  1190. char **pzErr, /* OUT: Error message, if any */
  1191. int isCreate /* True for xCreate, false for xConnect */
  1192. ){
  1193. int rc = SQLITE_OK;
  1194. Rtree *pRtree;
  1195. sqlite3_int64 nDb; /* Length of string argv[1] */
  1196. sqlite3_int64 nName; /* Length of string argv[2] */
  1197. sqlite3_str *pSql;
  1198. char *zSql;
  1199. int ii;
  1200. (void)pAux;
  1201. sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
  1202. sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  1203. /* Allocate the sqlite3_vtab structure */
  1204. nDb = strlen(argv[1]);
  1205. nName = strlen(argv[2]);
  1206. pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8);
  1207. if( !pRtree ){
  1208. return SQLITE_NOMEM;
  1209. }
  1210. memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8);
  1211. pRtree->nBusy = 1;
  1212. pRtree->base.pModule = &rtreeModule;
  1213. pRtree->zDb = (char *)&pRtree[1];
  1214. pRtree->zName = &pRtree->zDb[nDb+1];
  1215. pRtree->zNodeName = &pRtree->zName[nName+1];
  1216. pRtree->eCoordType = RTREE_COORD_REAL32;
  1217. pRtree->nDim = 2;
  1218. pRtree->nDim2 = 4;
  1219. memcpy(pRtree->zDb, argv[1], nDb);
  1220. memcpy(pRtree->zName, argv[2], nName);
  1221. memcpy(pRtree->zNodeName, argv[2], nName);
  1222. memcpy(&pRtree->zNodeName[nName], "_node", 6);
  1223. /* Create/Connect to the underlying relational database schema. If
  1224. ** that is successful, call sqlite3_declare_vtab() to configure
  1225. ** the r-tree table schema.
  1226. */
  1227. pSql = sqlite3_str_new(db);
  1228. sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape");
  1229. pRtree->nAux = 1; /* Add one for _shape */
  1230. pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */
  1231. for(ii=3; ii<argc; ii++){
  1232. pRtree->nAux++;
  1233. sqlite3_str_appendf(pSql, ",%s", argv[ii]);
  1234. }
  1235. sqlite3_str_appendf(pSql, ");");
  1236. zSql = sqlite3_str_finish(pSql);
  1237. if( !zSql ){
  1238. rc = SQLITE_NOMEM;
  1239. }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
  1240. *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
  1241. }
  1242. sqlite3_free(zSql);
  1243. if( rc ) goto geopolyInit_fail;
  1244. pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
  1245. /* Figure out the node size to use. */
  1246. rc = getNodeSize(db, pRtree, isCreate, pzErr);
  1247. if( rc ) goto geopolyInit_fail;
  1248. rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate);
  1249. if( rc ){
  1250. *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
  1251. goto geopolyInit_fail;
  1252. }
  1253. *ppVtab = (sqlite3_vtab *)pRtree;
  1254. return SQLITE_OK;
  1255. geopolyInit_fail:
  1256. if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
  1257. assert( *ppVtab==0 );
  1258. assert( pRtree->nBusy==1 );
  1259. rtreeRelease(pRtree);
  1260. return rc;
  1261. }
  1262. /*
  1263. ** GEOPOLY virtual table module xCreate method.
  1264. */
  1265. static int geopolyCreate(
  1266. sqlite3 *db,
  1267. void *pAux,
  1268. int argc, const char *const*argv,
  1269. sqlite3_vtab **ppVtab,
  1270. char **pzErr
  1271. ){
  1272. return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1);
  1273. }
  1274. /*
  1275. ** GEOPOLY virtual table module xConnect method.
  1276. */
  1277. static int geopolyConnect(
  1278. sqlite3 *db,
  1279. void *pAux,
  1280. int argc, const char *const*argv,
  1281. sqlite3_vtab **ppVtab,
  1282. char **pzErr
  1283. ){
  1284. return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0);
  1285. }
  1286. /*
  1287. ** GEOPOLY virtual table module xFilter method.
  1288. **
  1289. ** Query plans:
  1290. **
  1291. ** 1 rowid lookup
  1292. ** 2 search for objects overlapping the same bounding box
  1293. ** that contains polygon argv[0]
  1294. ** 3 search for objects overlapping the same bounding box
  1295. ** that contains polygon argv[0]
  1296. ** 4 full table scan
  1297. */
  1298. static int geopolyFilter(
  1299. sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */
  1300. int idxNum, /* Query plan */
  1301. const char *idxStr, /* Not Used */
  1302. int argc, sqlite3_value **argv /* Parameters to the query plan */
  1303. ){
  1304. Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
  1305. RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
  1306. RtreeNode *pRoot = 0;
  1307. int rc = SQLITE_OK;
  1308. int iCell = 0;
  1309. (void)idxStr;
  1310. rtreeReference(pRtree);
  1311. /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
  1312. resetCursor(pCsr);
  1313. pCsr->iStrategy = idxNum;
  1314. if( idxNum==1 ){
  1315. /* Special case - lookup by rowid. */
  1316. RtreeNode *pLeaf; /* Leaf on which the required cell resides */
  1317. RtreeSearchPoint *p; /* Search point for the leaf */
  1318. i64 iRowid = sqlite3_value_int64(argv[0]);
  1319. i64 iNode = 0;
  1320. rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
  1321. if( rc==SQLITE_OK && pLeaf!=0 ){
  1322. p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0);
  1323. assert( p!=0 ); /* Always returns pCsr->sPoint */
  1324. pCsr->aNode[0] = pLeaf;
  1325. p->id = iNode;
  1326. p->eWithin = PARTLY_WITHIN;
  1327. rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
  1328. p->iCell = (u8)iCell;
  1329. RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
  1330. }else{
  1331. pCsr->atEOF = 1;
  1332. }
  1333. }else{
  1334. /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array
  1335. ** with the configured constraints.
  1336. */
  1337. rc = nodeAcquire(pRtree, 1, 0, &pRoot);
  1338. if( rc==SQLITE_OK && idxNum<=3 ){
  1339. RtreeCoord bbox[4];
  1340. RtreeConstraint *p;
  1341. assert( argc==1 );
  1342. assert( argv[0]!=0 );
  1343. geopolyBBox(0, argv[0], bbox, &rc);
  1344. if( rc ){
  1345. goto geopoly_filter_end;
  1346. }
  1347. pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4);
  1348. pCsr->nConstraint = 4;
  1349. if( p==0 ){
  1350. rc = SQLITE_NOMEM;
  1351. }else{
  1352. memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4);
  1353. memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1));
  1354. if( idxNum==2 ){
  1355. /* Overlap query */
  1356. p->op = 'B';
  1357. p->iCoord = 0;
  1358. p->u.rValue = bbox[1].f;
  1359. p++;
  1360. p->op = 'D';
  1361. p->iCoord = 1;
  1362. p->u.rValue = bbox[0].f;
  1363. p++;
  1364. p->op = 'B';
  1365. p->iCoord = 2;
  1366. p->u.rValue = bbox[3].f;
  1367. p++;
  1368. p->op = 'D';
  1369. p->iCoord = 3;
  1370. p->u.rValue = bbox[2].f;
  1371. }else{
  1372. /* Within query */
  1373. p->op = 'D';
  1374. p->iCoord = 0;
  1375. p->u.rValue = bbox[0].f;
  1376. p++;
  1377. p->op = 'B';
  1378. p->iCoord = 1;
  1379. p->u.rValue = bbox[1].f;
  1380. p++;
  1381. p->op = 'D';
  1382. p->iCoord = 2;
  1383. p->u.rValue = bbox[2].f;
  1384. p++;
  1385. p->op = 'B';
  1386. p->iCoord = 3;
  1387. p->u.rValue = bbox[3].f;
  1388. }
  1389. }
  1390. }
  1391. if( rc==SQLITE_OK ){
  1392. RtreeSearchPoint *pNew;
  1393. pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
  1394. if( pNew==0 ){
  1395. rc = SQLITE_NOMEM;
  1396. goto geopoly_filter_end;
  1397. }
  1398. pNew->id = 1;
  1399. pNew->iCell = 0;
  1400. pNew->eWithin = PARTLY_WITHIN;
  1401. assert( pCsr->bPoint==1 );
  1402. pCsr->aNode[0] = pRoot;
  1403. pRoot = 0;
  1404. RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:");
  1405. rc = rtreeStepToLeaf(pCsr);
  1406. }
  1407. }
  1408. geopoly_filter_end:
  1409. nodeRelease(pRtree, pRoot);
  1410. rtreeRelease(pRtree);
  1411. return rc;
  1412. }
  1413. /*
  1414. ** Rtree virtual table module xBestIndex method. There are three
  1415. ** table scan strategies to choose from (in order from most to
  1416. ** least desirable):
  1417. **
  1418. ** idxNum idxStr Strategy
  1419. ** ------------------------------------------------
  1420. ** 1 "rowid" Direct lookup by rowid.
  1421. ** 2 "rtree" R-tree overlap query using geopoly_overlap()
  1422. ** 3 "rtree" R-tree within query using geopoly_within()
  1423. ** 4 "fullscan" full-table scan.
  1424. ** ------------------------------------------------
  1425. */
  1426. static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  1427. int ii;
  1428. int iRowidTerm = -1;
  1429. int iFuncTerm = -1;
  1430. int idxNum = 0;
  1431. (void)tab;
  1432. for(ii=0; ii<pIdxInfo->nConstraint; ii++){
  1433. struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
  1434. if( !p->usable ) continue;
  1435. if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
  1436. iRowidTerm = ii;
  1437. break;
  1438. }
  1439. if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
  1440. /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap()
  1441. ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within().
  1442. ** See geopolyFindFunction() */
  1443. iFuncTerm = ii;
  1444. idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2;
  1445. }
  1446. }
  1447. if( iRowidTerm>=0 ){
  1448. pIdxInfo->idxNum = 1;
  1449. pIdxInfo->idxStr = "rowid";
  1450. pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
  1451. pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
  1452. pIdxInfo->estimatedCost = 30.0;
  1453. pIdxInfo->estimatedRows = 1;
  1454. pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
  1455. return SQLITE_OK;
  1456. }
  1457. if( iFuncTerm>=0 ){
  1458. pIdxInfo->idxNum = idxNum;
  1459. pIdxInfo->idxStr = "rtree";
  1460. pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1;
  1461. pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0;
  1462. pIdxInfo->estimatedCost = 300.0;
  1463. pIdxInfo->estimatedRows = 10;
  1464. return SQLITE_OK;
  1465. }
  1466. pIdxInfo->idxNum = 4;
  1467. pIdxInfo->idxStr = "fullscan";
  1468. pIdxInfo->estimatedCost = 3000000.0;
  1469. pIdxInfo->estimatedRows = 100000;
  1470. return SQLITE_OK;
  1471. }
  1472. /*
  1473. ** GEOPOLY virtual table module xColumn method.
  1474. */
  1475. static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  1476. Rtree *pRtree = (Rtree *)cur->pVtab;
  1477. RtreeCursor *pCsr = (RtreeCursor *)cur;
  1478. RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
  1479. int rc = SQLITE_OK;
  1480. RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
  1481. if( rc ) return rc;
  1482. if( p==0 ) return SQLITE_OK;
  1483. if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK;
  1484. if( i<=pRtree->nAux ){
  1485. if( !pCsr->bAuxValid ){
  1486. if( pCsr->pReadAux==0 ){
  1487. rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0,
  1488. &pCsr->pReadAux, 0);
  1489. if( rc ) return rc;
  1490. }
  1491. sqlite3_bind_int64(pCsr->pReadAux, 1,
  1492. nodeGetRowid(pRtree, pNode, p->iCell));
  1493. rc = sqlite3_step(pCsr->pReadAux);
  1494. if( rc==SQLITE_ROW ){
  1495. pCsr->bAuxValid = 1;
  1496. }else{
  1497. sqlite3_reset(pCsr->pReadAux);
  1498. if( rc==SQLITE_DONE ) rc = SQLITE_OK;
  1499. return rc;
  1500. }
  1501. }
  1502. sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2));
  1503. }
  1504. return SQLITE_OK;
  1505. }
  1506. /*
  1507. ** The xUpdate method for GEOPOLY module virtual tables.
  1508. **
  1509. ** For DELETE:
  1510. **
  1511. ** argv[0] = the rowid to be deleted
  1512. **
  1513. ** For INSERT:
  1514. **
  1515. ** argv[0] = SQL NULL
  1516. ** argv[1] = rowid to insert, or an SQL NULL to select automatically
  1517. ** argv[2] = _shape column
  1518. ** argv[3] = first application-defined column....
  1519. **
  1520. ** For UPDATE:
  1521. **
  1522. ** argv[0] = rowid to modify. Never NULL
  1523. ** argv[1] = rowid after the change. Never NULL
  1524. ** argv[2] = new value for _shape
  1525. ** argv[3] = new value for first application-defined column....
  1526. */
  1527. static int geopolyUpdate(
  1528. sqlite3_vtab *pVtab,
  1529. int nData,
  1530. sqlite3_value **aData,
  1531. sqlite_int64 *pRowid
  1532. ){
  1533. Rtree *pRtree = (Rtree *)pVtab;
  1534. int rc = SQLITE_OK;
  1535. RtreeCell cell; /* New cell to insert if nData>1 */
  1536. i64 oldRowid; /* The old rowid */
  1537. int oldRowidValid; /* True if oldRowid is valid */
  1538. i64 newRowid; /* The new rowid */
  1539. int newRowidValid; /* True if newRowid is valid */
  1540. int coordChange = 0; /* Change in coordinates */
  1541. if( pRtree->nNodeRef ){
  1542. /* Unable to write to the btree while another cursor is reading from it,
  1543. ** since the write might do a rebalance which would disrupt the read
  1544. ** cursor. */
  1545. return SQLITE_LOCKED_VTAB;
  1546. }
  1547. rtreeReference(pRtree);
  1548. assert(nData>=1);
  1549. oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;;
  1550. oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0;
  1551. newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL;
  1552. newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0;
  1553. cell.iRowid = newRowid;
  1554. if( nData>1 /* not a DELETE */
  1555. && (!oldRowidValid /* INSERT */
  1556. || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */
  1557. || oldRowid!=newRowid) /* Rowid change */
  1558. ){
  1559. assert( aData[2]!=0 );
  1560. geopolyBBox(0, aData[2], cell.aCoord, &rc);
  1561. if( rc ){
  1562. if( rc==SQLITE_ERROR ){
  1563. pVtab->zErrMsg =
  1564. sqlite3_mprintf("_shape does not contain a valid polygon");
  1565. }
  1566. goto geopoly_update_end;
  1567. }
  1568. coordChange = 1;
  1569. /* If a rowid value was supplied, check if it is already present in
  1570. ** the table. If so, the constraint has failed. */
  1571. if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){
  1572. int steprc;
  1573. sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
  1574. steprc = sqlite3_step(pRtree->pReadRowid);
  1575. rc = sqlite3_reset(pRtree->pReadRowid);
  1576. if( SQLITE_ROW==steprc ){
  1577. if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
  1578. rc = rtreeDeleteRowid(pRtree, cell.iRowid);
  1579. }else{
  1580. rc = rtreeConstraintError(pRtree, 0);
  1581. }
  1582. }
  1583. }
  1584. }
  1585. /* If aData[0] is not an SQL NULL value, it is the rowid of a
  1586. ** record to delete from the r-tree table. The following block does
  1587. ** just that.
  1588. */
  1589. if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){
  1590. rc = rtreeDeleteRowid(pRtree, oldRowid);
  1591. }
  1592. /* If the aData[] array contains more than one element, elements
  1593. ** (aData[2]..aData[argc-1]) contain a new record to insert into
  1594. ** the r-tree structure.
  1595. */
  1596. if( rc==SQLITE_OK && nData>1 && coordChange ){
  1597. /* Insert the new record into the r-tree */
  1598. RtreeNode *pLeaf = 0;
  1599. if( !newRowidValid ){
  1600. rc = rtreeNewRowid(pRtree, &cell.iRowid);
  1601. }
  1602. *pRowid = cell.iRowid;
  1603. if( rc==SQLITE_OK ){
  1604. rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
  1605. }
  1606. if( rc==SQLITE_OK ){
  1607. int rc2;
  1608. rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
  1609. rc2 = nodeRelease(pRtree, pLeaf);
  1610. if( rc==SQLITE_OK ){
  1611. rc = rc2;
  1612. }
  1613. }
  1614. }
  1615. /* Change the data */
  1616. if( rc==SQLITE_OK && nData>1 ){
  1617. sqlite3_stmt *pUp = pRtree->pWriteAux;
  1618. int jj;
  1619. int nChange = 0;
  1620. sqlite3_bind_int64(pUp, 1, cell.iRowid);
  1621. assert( pRtree->nAux>=1 );
  1622. if( sqlite3_value_nochange(aData[2]) ){
  1623. sqlite3_bind_null(pUp, 2);
  1624. }else{
  1625. GeoPoly *p = 0;
  1626. if( sqlite3_value_type(aData[2])==SQLITE_TEXT
  1627. && (p = geopolyFuncParam(0, aData[2], &rc))!=0
  1628. && rc==SQLITE_OK
  1629. ){
  1630. sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
  1631. }else{
  1632. sqlite3_bind_value(pUp, 2, aData[2]);
  1633. }
  1634. sqlite3_free(p);
  1635. nChange = 1;
  1636. }
  1637. for(jj=1; jj<nData-2; jj++){
  1638. nChange++;
  1639. sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
  1640. }
  1641. if( nChange ){
  1642. sqlite3_step(pUp);
  1643. rc = sqlite3_reset(pUp);
  1644. }
  1645. }
  1646. geopoly_update_end:
  1647. rtreeRelease(pRtree);
  1648. return rc;
  1649. }
  1650. /*
  1651. ** Report that geopoly_overlap() is an overloaded function suitable
  1652. ** for use in xBestIndex.
  1653. */
  1654. static int geopolyFindFunction(
  1655. sqlite3_vtab *pVtab,
  1656. int nArg,
  1657. const char *zName,
  1658. void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
  1659. void **ppArg
  1660. ){
  1661. (void)pVtab;
  1662. (void)nArg;
  1663. if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){
  1664. *pxFunc = geopolyOverlapFunc;
  1665. *ppArg = 0;
  1666. return SQLITE_INDEX_CONSTRAINT_FUNCTION;
  1667. }
  1668. if( sqlite3_stricmp(zName, "geopoly_within")==0 ){
  1669. *pxFunc = geopolyWithinFunc;
  1670. *ppArg = 0;
  1671. return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
  1672. }
  1673. return 0;
  1674. }
  1675. static sqlite3_module geopolyModule = {
  1676. 3, /* iVersion */
  1677. geopolyCreate, /* xCreate - create a table */
  1678. geopolyConnect, /* xConnect - connect to an existing table */
  1679. geopolyBestIndex, /* xBestIndex - Determine search strategy */
  1680. rtreeDisconnect, /* xDisconnect - Disconnect from a table */
  1681. rtreeDestroy, /* xDestroy - Drop a table */
  1682. rtreeOpen, /* xOpen - open a cursor */
  1683. rtreeClose, /* xClose - close a cursor */
  1684. geopolyFilter, /* xFilter - configure scan constraints */
  1685. rtreeNext, /* xNext - advance a cursor */
  1686. rtreeEof, /* xEof */
  1687. geopolyColumn, /* xColumn - read data */
  1688. rtreeRowid, /* xRowid - read data */
  1689. geopolyUpdate, /* xUpdate - write data */
  1690. rtreeBeginTransaction, /* xBegin - begin transaction */
  1691. rtreeEndTransaction, /* xSync - sync transaction */
  1692. rtreeEndTransaction, /* xCommit - commit transaction */
  1693. rtreeEndTransaction, /* xRollback - rollback transaction */
  1694. geopolyFindFunction, /* xFindFunction - function overloading */
  1695. rtreeRename, /* xRename - rename the table */
  1696. rtreeSavepoint, /* xSavepoint */
  1697. 0, /* xRelease */
  1698. 0, /* xRollbackTo */
  1699. rtreeShadowName, /* xShadowName */
  1700. rtreeIntegrity /* xIntegrity */
  1701. };
  1702. static int sqlite3_geopoly_init(sqlite3 *db){
  1703. int rc = SQLITE_OK;
  1704. static const struct {
  1705. void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  1706. signed char nArg;
  1707. unsigned char bPure;
  1708. const char *zName;
  1709. } aFunc[] = {
  1710. { geopolyAreaFunc, 1, 1, "geopoly_area" },
  1711. { geopolyBlobFunc, 1, 1, "geopoly_blob" },
  1712. { geopolyJsonFunc, 1, 1, "geopoly_json" },
  1713. { geopolySvgFunc, -1, 1, "geopoly_svg" },
  1714. { geopolyWithinFunc, 2, 1, "geopoly_within" },
  1715. { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" },
  1716. { geopolyOverlapFunc, 2, 1, "geopoly_overlap" },
  1717. { geopolyDebugFunc, 1, 0, "geopoly_debug" },
  1718. { geopolyBBoxFunc, 1, 1, "geopoly_bbox" },
  1719. { geopolyXformFunc, 7, 1, "geopoly_xform" },
  1720. { geopolyRegularFunc, 4, 1, "geopoly_regular" },
  1721. { geopolyCcwFunc, 1, 1, "geopoly_ccw" },
  1722. };
  1723. static const struct {
  1724. void (*xStep)(sqlite3_context*,int,sqlite3_value**);
  1725. void (*xFinal)(sqlite3_context*);
  1726. const char *zName;
  1727. } aAgg[] = {
  1728. { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" },
  1729. };
  1730. unsigned int i;
  1731. for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
  1732. int enc;
  1733. if( aFunc[i].bPure ){
  1734. enc = SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS;
  1735. }else{
  1736. enc = SQLITE_UTF8|SQLITE_DIRECTONLY;
  1737. }
  1738. rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
  1739. enc, 0,
  1740. aFunc[i].xFunc, 0, 0);
  1741. }
  1742. for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
  1743. rc = sqlite3_create_function(db, aAgg[i].zName, 1,
  1744. SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS, 0,
  1745. 0, aAgg[i].xStep, aAgg[i].xFinal);
  1746. }
  1747. if( rc==SQLITE_OK ){
  1748. rc = sqlite3_create_module_v2(db, "geopoly", &geopolyModule, 0, 0);
  1749. }
  1750. return rc;
  1751. }