0000: 2f 2a 0a 2a 2a 20 32 30 31 38 2d 30 35 2d 32 35 /*.** 2018-05-25
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70 urce code. In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67 lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20 al notice, here
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20 *.** May you
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 do good and not
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20 evil..** May
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65 you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74 f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20 hers..** May
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79 you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76 ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 ****.**.** This
0180: 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 file implements
0190: 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65 20 52 an alternative R
01a0: 2d 54 72 65 65 20 76 69 72 74 75 61 6c 20 74 61 -Tree virtual ta
01b0: 62 6c 65 20 74 68 61 74 0a 2a 2a 20 75 73 65 73 ble that.** uses
01c0: 20 70 6f 6c 79 67 6f 6e 73 20 74 6f 20 65 78 70 polygons to exp
01d0: 72 65 73 73 20 74 68 65 20 62 6f 75 6e 64 61 72 ress the boundar
01e0: 69 65 73 20 6f 66 20 32 2d 64 69 6d 65 6e 73 69 ies of 2-dimensi
01f0: 6f 6e 61 6c 20 6f 62 6a 65 63 74 73 2e 0a 2a 2a onal objects..**
0200: 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 69 73 .** This file is
0210: 20 23 69 6e 63 6c 75 64 65 2d 65 64 20 6f 6e 74 #include-ed ont
0220: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 22 72 74 o the end of "rt
0230: 72 65 65 2e 63 22 20 73 6f 20 74 68 61 74 20 69 ree.c" so that i
0240: 74 20 68 61 73 0a 2a 2a 20 61 63 63 65 73 73 20 t has.** access
0250: 74 6f 20 61 6c 6c 20 6f 66 20 74 68 65 20 52 2d to all of the R-
0260: 54 72 65 65 20 69 6e 74 65 72 6e 61 6c 73 2e 0a Tree internals..
0270: 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 */.#include <std
0280: 6c 69 62 2e 68 3e 0a 0a 2f 2a 20 45 6e 61 62 6c lib.h>../* Enabl
0290: 65 20 2d 44 47 45 4f 50 4f 4c 59 5f 45 4e 41 42 e -DGEOPOLY_ENAB
02a0: 4c 45 5f 44 45 42 55 47 20 66 6f 72 20 64 65 62 LE_DEBUG for deb
02b0: 75 67 67 69 6e 67 20 66 61 63 69 6c 69 74 69 65 ugging facilitie
02c0: 73 20 2a 2f 0a 23 69 66 64 65 66 20 47 45 4f 50 s */.#ifdef GEOP
02d0: 4f 4c 59 5f 45 4e 41 42 4c 45 5f 44 45 42 55 47 OLY_ENABLE_DEBUG
02e0: 0a 20 20 73 74 61 74 69 63 20 69 6e 74 20 67 65 . static int ge
02f0: 6f 5f 64 65 62 75 67 20 3d 20 30 3b 0a 23 20 64 o_debug = 0;.# d
0300: 65 66 69 6e 65 20 47 45 4f 44 45 42 55 47 28 58 efine GEODEBUG(X
0310: 29 20 69 66 28 67 65 6f 5f 64 65 62 75 67 29 70 ) if(geo_debug)p
0320: 72 69 6e 74 66 20 58 0a 23 65 6c 73 65 0a 23 20 rintf X.#else.#
0330: 64 65 66 69 6e 65 20 47 45 4f 44 45 42 55 47 28 define GEODEBUG(
0340: 58 29 0a 23 65 6e 64 69 66 0a 0a 23 69 66 6e 64 X).#endif..#ifnd
0350: 65 66 20 4a 53 4f 4e 5f 4e 55 4c 4c 20 20 20 2f ef JSON_NULL /
0360: 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 * The following
0370: 73 74 75 66 66 20 72 65 70 65 61 74 73 20 74 68 stuff repeats th
0380: 69 6e 67 73 20 66 6f 75 6e 64 20 69 6e 20 6a 73 ings found in js
0390: 6f 6e 31 20 2a 2f 0a 2f 2a 0a 2a 2a 20 56 65 72 on1 */./*.** Ver
03a0: 73 69 6f 6e 73 20 6f 66 20 69 73 73 70 61 63 65 sions of isspace
03b0: 28 29 2c 20 69 73 61 6c 6e 75 6d 28 29 20 61 6e (), isalnum() an
03c0: 64 20 69 73 64 69 67 69 74 28 29 20 74 6f 20 77 d isdigit() to w
03d0: 68 69 63 68 20 69 74 20 69 73 20 73 61 66 65 0a hich it is safe.
03e0: 2a 2a 20 74 6f 20 70 61 73 73 20 73 69 67 6e 65 ** to pass signe
03f0: 64 20 63 68 61 72 20 76 61 6c 75 65 73 2e 0a 2a d char values..*
0400: 2f 0a 23 69 66 64 65 66 20 73 71 6c 69 74 65 33 /.#ifdef sqlite3
0410: 49 73 64 69 67 69 74 0a 20 20 20 2f 2a 20 55 73 Isdigit. /* Us
0420: 65 20 74 68 65 20 53 51 4c 69 74 65 20 63 6f 72 e the SQLite cor
0430: 65 20 76 65 72 73 69 6f 6e 73 20 69 66 20 74 68 e versions if th
0440: 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 70 61 is routine is pa
0450: 72 74 20 6f 66 20 74 68 65 0a 20 20 20 2a 2a 20 rt of the. **
0460: 53 51 4c 69 74 65 20 61 6d 61 6c 67 61 6d 61 74 SQLite amalgamat
0470: 69 6f 6e 20 2a 2f 0a 23 20 20 64 65 66 69 6e 65 ion */.# define
0480: 20 73 61 66 65 5f 69 73 64 69 67 69 74 28 78 29 safe_isdigit(x)
0490: 20 20 73 71 6c 69 74 65 33 49 73 64 69 67 69 74 sqlite3Isdigit
04a0: 28 78 29 0a 23 20 20 64 65 66 69 6e 65 20 73 61 (x).# define sa
04b0: 66 65 5f 69 73 61 6c 6e 75 6d 28 78 29 20 20 73 fe_isalnum(x) s
04c0: 71 6c 69 74 65 33 49 73 61 6c 6e 75 6d 28 78 29 qlite3Isalnum(x)
04d0: 0a 23 20 20 64 65 66 69 6e 65 20 73 61 66 65 5f .# define safe_
04e0: 69 73 78 64 69 67 69 74 28 78 29 20 73 71 6c 69 isxdigit(x) sqli
04f0: 74 65 33 49 73 78 64 69 67 69 74 28 78 29 0a 23 te3Isxdigit(x).#
0500: 65 6c 73 65 0a 20 20 20 2f 2a 20 55 73 65 20 74 else. /* Use t
0510: 68 65 20 73 74 61 6e 64 61 72 64 20 6c 69 62 72 he standard libr
0520: 61 72 79 20 66 6f 72 20 73 65 70 61 72 61 74 65 ary for separate
0530: 20 63 6f 6d 70 69 6c 61 74 69 6f 6e 20 2a 2f 0a compilation */.
0540: 23 69 6e 63 6c 75 64 65 20 3c 63 74 79 70 65 2e #include <ctype.
0550: 68 3e 20 20 2f 2a 20 61 6d 61 6c 67 61 6d 61 74 h> /* amalgamat
0560: 6f 72 3a 20 6b 65 65 70 20 2a 2f 0a 23 20 20 64 or: keep */.# d
0570: 65 66 69 6e 65 20 73 61 66 65 5f 69 73 64 69 67 efine safe_isdig
0580: 69 74 28 78 29 20 20 69 73 64 69 67 69 74 28 28 it(x) isdigit((
0590: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28 78 unsigned char)(x
05a0: 29 29 0a 23 20 20 64 65 66 69 6e 65 20 73 61 66 )).# define saf
05b0: 65 5f 69 73 61 6c 6e 75 6d 28 78 29 20 20 69 73 e_isalnum(x) is
05c0: 61 6c 6e 75 6d 28 28 75 6e 73 69 67 6e 65 64 20 alnum((unsigned
05d0: 63 68 61 72 29 28 78 29 29 0a 23 20 20 64 65 66 char)(x)).# def
05e0: 69 6e 65 20 73 61 66 65 5f 69 73 78 64 69 67 69 ine safe_isxdigi
05f0: 74 28 78 29 20 69 73 78 64 69 67 69 74 28 28 75 t(x) isxdigit((u
0600: 6e 73 69 67 6e 65 64 20 63 68 61 72 29 28 78 29 nsigned char)(x)
0610: 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 ).#endif../*.**
0620: 47 72 6f 77 69 6e 67 20 6f 75 72 20 6f 77 6e 20 Growing our own
0630: 69 73 73 70 61 63 65 28 29 20 72 6f 75 74 69 6e isspace() routin
0640: 65 20 74 68 69 73 20 77 61 79 20 69 73 20 74 77 e this way is tw
0650: 69 63 65 20 61 73 20 66 61 73 74 20 61 73 0a 2a ice as fast as.*
0660: 2a 20 74 68 65 20 6c 69 62 72 61 72 79 20 69 73 * the library is
0670: 73 70 61 63 65 28 29 20 66 75 6e 63 74 69 6f 6e space() function
0680: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 ..*/.static cons
0690: 74 20 63 68 61 72 20 67 65 6f 70 6f 6c 79 49 73 t char geopolyIs
06a0: 53 70 61 63 65 5b 5d 20 3d 20 7b 0a 20 20 30 2c Space[] = {. 0,
06b0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0, 0,
06c0: 30 2c 20 30 2c 20 20 20 20 20 30 2c 20 31 2c 20 0, 0, 0, 1,
06d0: 31 2c 20 30 2c 20 30 2c 20 31 2c 20 30 2c 20 30 1, 0, 0, 1, 0, 0
06e0: 2c 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 ,. 0, 0, 0, 0,
06f0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 20 20 0, 0, 0, 0,
0700: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0, 0
0710: 2c 20 30 2c 20 30 2c 0a 20 20 31 2c 20 30 2c 20 , 0, 0,. 1, 0,
0720: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0, 0
0730: 2c 20 20 20 20 20 30 2c 20 30 2c 20 30 2c 20 30 , 0, 0, 0, 0
0740: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0a 20 20 , 0, 0, 0, 0,.
0750: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0, 0
0760: 2c 20 30 2c 20 30 2c 20 20 20 20 20 30 2c 20 30 , 0, 0, 0, 0
0770: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c , 0, 0, 0, 0, 0,
0780: 20 30 2c 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30 0,. 0, 0, 0, 0
0790: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 , 0, 0, 0, 0,
07a0: 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0, 0, 0, 0, 0,
07b0: 20 30 2c 20 30 2c 20 30 2c 0a 20 20 30 2c 20 30 0, 0, 0,. 0, 0
07c0: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c , 0, 0, 0, 0, 0,
07d0: 20 30 2c 20 20 20 20 20 30 2c 20 30 2c 20 30 2c 0, 0, 0, 0,
07e0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0a 0, 0, 0, 0, 0,.
07f0: 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0, 0, 0, 0, 0,
0800: 20 30 2c 20 30 2c 20 30 2c 20 20 20 20 20 30 2c 0, 0, 0, 0,
0810: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0, 0,
0820: 30 2c 20 30 2c 0a 20 20 30 2c 20 30 2c 20 30 2c 0, 0,. 0, 0, 0,
0830: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0, 0,
0840: 20 20 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0,
0850: 30 2c 20 30 2c 20 30 2c 20 30 2c 0a 20 20 30 2c 0, 0, 0, 0,. 0,
0860: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0, 0,
0870: 30 2c 20 30 2c 20 20 20 20 20 30 2c 20 30 2c 20 0, 0, 0, 0,
0880: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0, 0
0890: 2c 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 ,. 0, 0, 0, 0,
08a0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 20 20 0, 0, 0, 0,
08b0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0, 0
08c0: 2c 20 30 2c 20 30 2c 0a 20 20 30 2c 20 30 2c 20 , 0, 0,. 0, 0,
08d0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0, 0
08e0: 2c 20 20 20 20 20 30 2c 20 30 2c 20 30 2c 20 30 , 0, 0, 0, 0
08f0: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0a 20 20 , 0, 0, 0, 0,.
0900: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0, 0
0910: 2c 20 30 2c 20 30 2c 20 20 20 20 20 30 2c 20 30 , 0, 0, 0, 0
0920: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c , 0, 0, 0, 0, 0,
0930: 20 30 2c 0a 20 20 30 2c 20 30 2c 20 30 2c 20 30 0,. 0, 0, 0, 0
0940: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 , 0, 0, 0, 0,
0950: 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0, 0, 0, 0, 0,
0960: 20 30 2c 20 30 2c 20 30 2c 0a 20 20 30 2c 20 30 0, 0, 0,. 0, 0
0970: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c , 0, 0, 0, 0, 0,
0980: 20 30 2c 20 20 20 20 20 30 2c 20 30 2c 20 30 2c 0, 0, 0, 0,
0990: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0a 0, 0, 0, 0, 0,.
09a0: 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 0, 0, 0, 0, 0,
09b0: 20 30 2c 20 30 2c 20 30 2c 20 20 20 20 20 30 2c 0, 0, 0, 0,
09c0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0, 0,
09d0: 30 2c 20 30 2c 0a 20 20 30 2c 20 30 2c 20 30 2c 0, 0,. 0, 0, 0,
09e0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0, 0,
09f0: 20 20 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0,
0a00: 30 2c 20 30 2c 20 30 2c 20 30 2c 0a 7d 3b 0a 23 0, 0, 0, 0,.};.#
0a10: 64 65 66 69 6e 65 20 73 61 66 65 5f 69 73 73 70 define safe_issp
0a20: 61 63 65 28 78 29 20 28 67 65 6f 70 6f 6c 79 49 ace(x) (geopolyI
0a30: 73 53 70 61 63 65 5b 28 75 6e 73 69 67 6e 65 64 sSpace[(unsigned
0a40: 20 63 68 61 72 29 78 5d 29 0a 23 65 6e 64 69 66 char)x]).#endif
0a50: 20 2f 2a 20 4a 53 4f 4e 20 4e 55 4c 4c 20 2d 20 /* JSON NULL -
0a60: 62 61 63 6b 20 74 6f 20 6f 72 69 67 69 6e 61 6c back to original
0a70: 20 63 6f 64 65 20 2a 2f 0a 0a 2f 2a 20 43 6f 6d code */../* Com
0a80: 70 69 6c 65 72 20 61 6e 64 20 76 65 72 73 69 6f piler and versio
0a90: 6e 20 2a 2f 0a 23 69 66 6e 64 65 66 20 47 43 43 n */.#ifndef GCC
0aa0: 5f 56 45 52 53 49 4f 4e 0a 23 69 66 20 64 65 66 _VERSION.#if def
0ab0: 69 6e 65 64 28 5f 5f 47 4e 55 43 5f 5f 29 20 26 ined(__GNUC__) &
0ac0: 26 20 21 64 65 66 69 6e 65 64 28 53 51 4c 49 54 & !defined(SQLIT
0ad0: 45 5f 44 49 53 41 42 4c 45 5f 49 4e 54 52 49 4e E_DISABLE_INTRIN
0ae0: 53 49 43 29 0a 23 20 64 65 66 69 6e 65 20 47 43 SIC).# define GC
0af0: 43 5f 56 45 52 53 49 4f 4e 20 28 5f 5f 47 4e 55 C_VERSION (__GNU
0b00: 43 5f 5f 2a 31 30 30 30 30 30 30 2b 5f 5f 47 4e C__*1000000+__GN
0b10: 55 43 5f 4d 49 4e 4f 52 5f 5f 2a 31 30 30 30 2b UC_MINOR__*1000+
0b20: 5f 5f 47 4e 55 43 5f 50 41 54 43 48 4c 45 56 45 __GNUC_PATCHLEVE
0b30: 4c 5f 5f 29 0a 23 65 6c 73 65 0a 23 20 64 65 66 L__).#else.# def
0b40: 69 6e 65 20 47 43 43 5f 56 45 52 53 49 4f 4e 20 ine GCC_VERSION
0b50: 30 0a 23 65 6e 64 69 66 0a 23 65 6e 64 69 66 0a 0.#endif.#endif.
0b60: 23 69 66 6e 64 65 66 20 4d 53 56 43 5f 56 45 52 #ifndef MSVC_VER
0b70: 53 49 4f 4e 0a 23 69 66 20 64 65 66 69 6e 65 64 SION.#if defined
0b80: 28 5f 4d 53 43 5f 56 45 52 29 20 26 26 20 21 64 (_MSC_VER) && !d
0b90: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 49 efined(SQLITE_DI
0ba0: 53 41 42 4c 45 5f 49 4e 54 52 49 4e 53 49 43 29 SABLE_INTRINSIC)
0bb0: 0a 23 20 64 65 66 69 6e 65 20 4d 53 56 43 5f 56 .# define MSVC_V
0bc0: 45 52 53 49 4f 4e 20 5f 4d 53 43 5f 56 45 52 0a ERSION _MSC_VER.
0bd0: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 4d #else.# define M
0be0: 53 56 43 5f 56 45 52 53 49 4f 4e 20 30 0a 23 65 SVC_VERSION 0.#e
0bf0: 6e 64 69 66 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 ndif.#endif../*
0c00: 44 61 74 61 74 79 70 65 20 66 6f 72 20 63 6f 6f Datatype for coo
0c10: 72 64 69 6e 61 74 65 73 0a 2a 2f 0a 74 79 70 65 rdinates.*/.type
0c20: 64 65 66 20 66 6c 6f 61 74 20 47 65 6f 43 6f 6f def float GeoCoo
0c30: 72 64 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6e 74 65 72 rd;../*.** Inter
0c40: 6e 61 6c 20 72 65 70 72 65 73 65 6e 74 61 74 69 nal representati
0c50: 6f 6e 20 6f 66 20 61 20 70 6f 6c 79 67 6f 6e 2e on of a polygon.
0c60: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 6f 6c 79 67 .**.** The polyg
0c70: 6f 6e 20 63 6f 6e 73 69 73 74 73 20 6f 66 20 61 on consists of a
0c80: 20 73 65 71 75 65 6e 63 65 20 6f 66 20 76 65 72 sequence of ver
0c90: 74 65 78 65 73 2e 20 20 54 68 65 72 65 20 69 73 texes. There is
0ca0: 20 61 20 6c 69 6e 65 0a 2a 2a 20 73 65 67 6d 65 a line.** segme
0cb0: 6e 74 20 62 65 74 77 65 65 6e 20 65 61 63 68 20 nt between each
0cc0: 70 61 69 72 20 6f 66 20 76 65 72 74 65 78 65 73 pair of vertexes
0cd0: 2c 20 61 6e 64 20 6f 6e 65 20 66 69 6e 61 6c 20 , and one final
0ce0: 73 65 67 6d 65 6e 74 20 66 72 6f 6d 0a 2a 2a 20 segment from.**
0cf0: 74 68 65 20 6c 61 73 74 20 76 65 72 74 65 78 20 the last vertex
0d00: 62 61 63 6b 20 74 6f 20 74 68 65 20 66 69 72 73 back to the firs
0d10: 74 2e 20 20 28 54 68 69 73 20 64 69 66 66 65 72 t. (This differ
0d20: 73 20 66 72 6f 6d 20 74 68 65 20 47 65 6f 4a 53 s from the GeoJS
0d30: 4f 4e 0a 2a 2a 20 73 74 61 6e 64 61 72 64 20 69 ON.** standard i
0d40: 6e 20 77 68 69 63 68 20 74 68 65 20 66 69 6e 61 n which the fina
0d50: 6c 20 76 65 72 74 65 78 20 69 73 20 61 20 72 65 l vertex is a re
0d60: 70 65 61 74 20 6f 66 20 74 68 65 20 66 69 72 73 peat of the firs
0d70: 74 2e 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 6f t.).**.** The po
0d80: 6c 79 67 6f 6e 20 66 6f 6c 6c 6f 77 73 20 74 68 lygon follows th
0d90: 65 20 72 69 67 68 74 2d 68 61 6e 64 20 72 75 6c e right-hand rul
0da0: 65 2e 20 20 54 68 65 20 61 72 65 61 20 74 6f 20 e. The area to
0db0: 74 68 65 20 72 69 67 68 74 20 6f 66 0a 2a 2a 20 the right of.**
0dc0: 65 61 63 68 20 73 65 67 6d 65 6e 74 20 69 73 20 each segment is
0dd0: 22 6f 75 74 73 69 64 65 22 20 61 6e 64 20 74 68 "outside" and th
0de0: 65 20 61 72 65 61 20 74 6f 20 74 68 65 20 6c 65 e area to the le
0df0: 66 74 20 69 73 20 22 69 6e 73 69 64 65 22 2e 0a ft is "inside"..
0e00: 2a 2a 0a 2a 2a 20 54 68 65 20 6f 6e 2d 64 69 73 **.** The on-dis
0e10: 6b 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f 6e k representation
0e20: 20 63 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 34 consists of a 4
0e30: 2d 62 79 74 65 20 68 65 61 64 65 72 20 66 6f 6c -byte header fol
0e40: 6c 6f 77 65 64 20 62 79 0a 2a 2a 20 74 68 65 20 lowed by.** the
0e50: 76 61 6c 75 65 73 2e 20 20 54 68 65 20 34 2d 62 values. The 4-b
0e60: 79 74 65 20 68 65 61 64 65 72 20 69 73 3a 0a 2a yte header is:.*
0e70: 2a 0a 2a 2a 20 20 20 20 20 20 65 6e 63 6f 64 69 *.** encodi
0e80: 6e 67 20 20 20 20 28 31 20 62 79 74 65 29 20 20 ng (1 byte)
0e90: 20 30 3d 62 69 67 2d 65 6e 64 69 61 6e 2c 20 31 0=big-endian, 1
0ea0: 3d 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a =little-endian.*
0eb0: 2a 20 20 20 20 20 20 6e 76 65 72 74 65 78 20 20 * nvertex
0ec0: 20 20 20 28 33 20 62 79 74 65 73 29 20 20 4e 75 (3 bytes) Nu
0ed0: 6d 62 65 72 20 6f 66 20 76 65 72 74 65 78 65 73 mber of vertexes
0ee0: 20 61 73 20 61 20 62 69 67 2d 65 6e 64 69 61 6e as a big-endian
0ef0: 20 69 6e 74 65 67 65 72 0a 2a 2a 0a 2a 2a 20 45 integer.**.** E
0f00: 6e 6f 75 67 68 20 73 70 61 63 65 20 69 73 20 61 nough space is a
0f10: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 34 20 63 llocated for 4 c
0f20: 6f 6f 72 64 69 6e 61 74 65 73 2c 20 74 6f 20 77 oordinates, to w
0f30: 6f 72 6b 20 61 72 6f 75 6e 64 20 6f 76 65 72 2d ork around over-
0f40: 7a 65 61 6c 6f 75 73 0a 2a 2a 20 77 61 72 6e 69 zealous.** warni
0f50: 6e 67 73 20 63 6f 6d 69 6e 67 20 66 72 6f 6d 20 ngs coming from
0f60: 73 6f 6d 65 20 63 6f 6d 70 69 6c 65 72 20 28 6e some compiler (n
0f70: 6f 74 61 62 6c 79 2c 20 63 6c 61 6e 67 29 2e 20 otably, clang).
0f80: 49 6e 20 72 65 61 6c 69 74 79 2c 20 74 68 65 20 In reality, the
0f90: 73 69 7a 65 0a 2a 2a 20 6f 66 20 65 61 63 68 20 size.** of each
0fa0: 47 65 6f 50 6f 6c 79 20 6d 65 6d 6f 72 79 20 61 GeoPoly memory a
0fb0: 6c 6c 6f 63 61 74 65 20 69 73 20 61 64 6a 75 73 llocate is adjus
0fc0: 74 65 64 20 61 73 20 6e 65 63 65 73 73 61 72 79 ted as necessary
0fd0: 20 73 6f 20 74 68 61 74 20 74 68 65 0a 2a 2a 20 so that the.**
0fe0: 47 65 6f 50 6f 6c 79 2e 61 5b 5d 20 61 72 72 61 GeoPoly.a[] arra
0ff0: 79 20 61 74 20 74 68 65 20 65 6e 64 20 69 73 20 y at the end is
1000: 74 68 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 the appropriate
1010: 73 69 7a 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 size..*/.typedef
1020: 20 73 74 72 75 63 74 20 47 65 6f 50 6f 6c 79 20 struct GeoPoly
1030: 47 65 6f 50 6f 6c 79 3b 0a 73 74 72 75 63 74 20 GeoPoly;.struct
1040: 47 65 6f 50 6f 6c 79 20 7b 0a 20 20 69 6e 74 20 GeoPoly {. int
1050: 6e 56 65 72 74 65 78 3b 20 20 20 20 20 20 20 20 nVertex;
1060: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76 /* Number of v
1070: 65 72 74 65 78 65 73 20 2a 2f 0a 20 20 75 6e 73 ertexes */. uns
1080: 69 67 6e 65 64 20 63 68 61 72 20 68 64 72 5b 34 igned char hdr[4
1090: 5d 3b 20 2f 2a 20 48 65 61 64 65 72 20 66 6f 72 ]; /* Header for
10a0: 20 6f 6e 2d 64 69 73 6b 20 72 65 70 72 65 73 65 on-disk represe
10b0: 6e 74 61 74 69 6f 6e 20 2a 2f 0a 20 20 47 65 6f ntation */. Geo
10c0: 43 6f 6f 72 64 20 61 5b 38 5d 3b 20 20 20 20 20 Coord a[8];
10d0: 20 20 20 2f 2a 20 32 2a 6e 56 65 72 74 65 78 20 /* 2*nVertex
10e0: 76 61 6c 75 65 73 2e 20 58 20 28 6c 6f 6e 67 69 values. X (longi
10f0: 74 75 64 65 29 20 66 69 72 73 74 2c 20 74 68 65 tude) first, the
1100: 6e 20 59 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 54 68 n Y */.};../* Th
1110: 65 20 73 69 7a 65 20 6f 66 20 61 20 6d 65 6d 6f e size of a memo
1120: 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6e 65 ry allocation ne
1130: 65 64 65 64 20 66 6f 72 20 61 20 47 65 6f 50 6f eded for a GeoPo
1140: 6c 79 20 6f 62 6a 65 63 74 20 73 75 66 66 69 63 ly object suffic
1150: 69 65 6e 74 0a 2a 2a 20 74 6f 20 68 6f 6c 64 20 ient.** to hold
1160: 4e 20 63 6f 6f 72 64 69 6e 61 74 65 20 70 61 69 N coordinate pai
1170: 72 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 47 rs..*/.#define G
1180: 45 4f 50 4f 4c 59 5f 53 5a 28 4e 29 20 20 28 73 EOPOLY_SZ(N) (s
1190: 69 7a 65 6f 66 28 47 65 6f 50 6f 6c 79 29 20 2b izeof(GeoPoly) +
11a0: 20 73 69 7a 65 6f 66 28 47 65 6f 43 6f 6f 72 64 sizeof(GeoCoord
11b0: 29 2a 32 2a 28 28 4e 29 2d 34 29 29 0a 0a 2f 2a )*2*((N)-4))../*
11c0: 20 4d 61 63 72 6f 73 20 74 6f 20 61 63 63 65 73 Macros to acces
11d0: 73 20 63 6f 6f 72 64 69 6e 61 74 65 73 20 6f 66 s coordinates of
11e0: 20 61 20 47 65 6f 50 6f 6c 79 2e 0a 2a 2a 20 57 a GeoPoly..** W
11f0: 65 20 68 61 76 65 20 74 6f 20 75 73 65 20 74 68 e have to use th
1200: 65 73 65 20 6d 61 63 72 6f 73 2c 20 72 61 74 68 ese macros, rath
1210: 65 72 20 74 68 61 6e 20 6a 75 73 74 20 73 61 79 er than just say
1220: 20 70 2d 3e 61 5b 69 5d 20 69 6e 20 6f 72 64 65 p->a[i] in orde
1230: 72 0a 2a 2a 20 74 6f 20 73 69 6c 65 6e 63 65 20 r.** to silence
1240: 28 69 6e 63 6f 72 72 65 63 74 29 20 55 42 53 41 (incorrect) UBSA
1250: 4e 20 77 61 72 6e 69 6e 67 73 20 69 66 20 74 68 N warnings if th
1260: 65 20 61 72 72 61 79 20 69 6e 64 65 78 20 69 73 e array index is
1270: 20 74 6f 6f 20 6c 61 72 67 65 2e 0a 2a 2f 0a 23 too large..*/.#
1280: 64 65 66 69 6e 65 20 47 65 6f 58 28 50 2c 49 29 define GeoX(P,I)
1290: 20 20 28 28 28 47 65 6f 43 6f 6f 72 64 2a 29 28 (((GeoCoord*)(
12a0: 50 29 2d 3e 61 29 5b 28 49 29 2a 32 5d 29 0a 23 P)->a)[(I)*2]).#
12b0: 64 65 66 69 6e 65 20 47 65 6f 59 28 50 2c 49 29 define GeoY(P,I)
12c0: 20 20 28 28 28 47 65 6f 43 6f 6f 72 64 2a 29 28 (((GeoCoord*)(
12d0: 50 29 2d 3e 61 29 5b 28 49 29 2a 32 2b 31 5d 29 P)->a)[(I)*2+1])
12e0: 0a 0a 0a 2f 2a 0a 2a 2a 20 53 74 61 74 65 20 6f .../*.** State o
12f0: 66 20 61 20 70 61 72 73 65 20 6f 66 20 61 20 47 f a parse of a G
1300: 65 6f 4a 53 4f 4e 20 69 6e 70 75 74 2e 0a 2a 2f eoJSON input..*/
1310: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 .typedef struct
1320: 47 65 6f 50 61 72 73 65 20 47 65 6f 50 61 72 73 GeoParse GeoPars
1330: 65 3b 0a 73 74 72 75 63 74 20 47 65 6f 50 61 72 e;.struct GeoPar
1340: 73 65 20 7b 0a 20 20 63 6f 6e 73 74 20 75 6e 73 se {. const uns
1350: 69 67 6e 65 64 20 63 68 61 72 20 2a 7a 3b 20 20 igned char *z;
1360: 20 2f 2a 20 55 6e 70 61 72 73 65 64 20 69 6e 70 /* Unparsed inp
1370: 75 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 56 65 72 ut */. int nVer
1380: 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 tex;
1390: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76 /* Number of v
13a0: 65 72 74 65 78 65 73 20 69 6e 20 61 5b 5d 20 2a ertexes in a[] *
13b0: 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f 63 3b 20 /. int nAlloc;
13c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
13d0: 20 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 65 64 Space allocated
13e0: 20 74 6f 20 61 5b 5d 20 2a 2f 0a 20 20 69 6e 74 to a[] */. int
13f0: 20 6e 45 72 72 3b 20 20 20 20 20 20 20 20 20 20 nErr;
1400: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 /* Number
1410: 20 6f 66 20 65 72 72 6f 72 73 20 65 6e 63 6f 75 of errors encou
1420: 6e 74 65 72 65 64 20 2a 2f 0a 20 20 47 65 6f 43 ntered */. GeoC
1430: 6f 6f 72 64 20 2a 61 3b 20 20 20 20 20 20 20 20 oord *a;
1440: 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 76 65 /* Array of ve
1450: 72 74 65 78 65 73 2e 20 20 46 72 6f 6d 20 73 71 rtexes. From sq
1460: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 29 lite3_malloc64()
1470: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 44 6f 20 61 20 */.};../* Do a
1480: 34 2d 62 79 74 65 20 62 79 74 65 20 73 77 61 70 4-byte byte swap
1490: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 */.static void
14a0: 67 65 6f 70 6f 6c 79 53 77 61 62 33 32 28 75 6e geopolySwab32(un
14b0: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 61 29 7b signed char *a){
14c0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 . unsigned char
14d0: 20 74 20 3d 20 61 5b 30 5d 3b 0a 20 20 61 5b 30 t = a[0];. a[0
14e0: 5d 20 3d 20 61 5b 33 5d 3b 0a 20 20 61 5b 33 5d ] = a[3];. a[3]
14f0: 20 3d 20 74 3b 0a 20 20 74 20 3d 20 61 5b 31 5d = t;. t = a[1]
1500: 3b 0a 20 20 61 5b 31 5d 20 3d 20 61 5b 32 5d 3b ;. a[1] = a[2];
1510: 0a 20 20 61 5b 32 5d 20 3d 20 74 3b 0a 7d 0a 0a . a[2] = t;.}..
1520: 2f 2a 20 53 6b 69 70 20 77 68 69 74 65 73 70 61 /* Skip whitespa
1530: 63 65 2e 20 20 52 65 74 75 72 6e 20 74 68 65 20 ce. Return the
1540: 6e 65 78 74 20 6e 6f 6e 2d 77 68 69 74 65 73 70 next non-whitesp
1550: 61 63 65 20 63 68 61 72 61 63 74 65 72 2e 20 2a ace character. *
1560: 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 67 65 /.static char ge
1570: 6f 70 6f 6c 79 53 6b 69 70 53 70 61 63 65 28 47 opolySkipSpace(G
1580: 65 6f 50 61 72 73 65 20 2a 70 29 7b 0a 20 20 77 eoParse *p){. w
1590: 68 69 6c 65 28 20 73 61 66 65 5f 69 73 73 70 61 hile( safe_isspa
15a0: 63 65 28 70 2d 3e 7a 5b 30 5d 29 20 29 20 70 2d ce(p->z[0]) ) p-
15b0: 3e 7a 2b 2b 3b 0a 20 20 72 65 74 75 72 6e 20 70 >z++;. return p
15c0: 2d 3e 7a 5b 30 5d 3b 0a 7d 0a 0a 2f 2a 20 50 61 ->z[0];.}../* Pa
15d0: 72 73 65 20 6f 75 74 20 61 20 6e 75 6d 62 65 72 rse out a number
15e0: 2e 20 20 57 72 69 74 65 20 74 68 65 20 76 61 6c . Write the val
15f0: 75 65 20 69 6e 74 6f 20 2a 70 56 61 6c 20 69 66 ue into *pVal if
1600: 20 70 56 61 6c 21 3d 30 2e 0a 2a 2a 20 72 65 74 pVal!=0..** ret
1610: 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 20 6f 6e 20 urn non-zero on
1620: 73 75 63 63 65 73 73 20 61 6e 64 20 7a 65 72 6f success and zero
1630: 20 69 66 20 74 68 65 20 6e 65 78 74 20 74 6f 6b if the next tok
1640: 65 6e 20 69 73 20 6e 6f 74 20 61 20 6e 75 6d 62 en is not a numb
1650: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e er..*/.static in
1660: 74 20 67 65 6f 70 6f 6c 79 50 61 72 73 65 4e 75 t geopolyParseNu
1670: 6d 62 65 72 28 47 65 6f 50 61 72 73 65 20 2a 70 mber(GeoParse *p
1680: 2c 20 47 65 6f 43 6f 6f 72 64 20 2a 70 56 61 6c , GeoCoord *pVal
1690: 29 7b 0a 20 20 63 68 61 72 20 63 20 3d 20 67 65 ){. char c = ge
16a0: 6f 70 6f 6c 79 53 6b 69 70 53 70 61 63 65 28 70 opolySkipSpace(p
16b0: 29 3b 0a 20 20 63 6f 6e 73 74 20 75 6e 73 69 67 );. const unsig
16c0: 6e 65 64 20 63 68 61 72 20 2a 7a 20 3d 20 70 2d ned char *z = p-
16d0: 3e 7a 3b 0a 20 20 69 6e 74 20 6a 20 3d 20 30 3b >z;. int j = 0;
16e0: 0a 20 20 69 6e 74 20 73 65 65 6e 44 50 20 3d 20 . int seenDP =
16f0: 30 3b 0a 20 20 69 6e 74 20 73 65 65 6e 45 20 3d 0;. int seenE =
1700: 20 30 3b 0a 20 20 69 66 28 20 63 3d 3d 27 2d 27 0;. if( c=='-'
1710: 20 29 7b 0a 20 20 20 20 6a 20 3d 20 31 3b 0a 20 ){. j = 1;.
1720: 20 20 20 63 20 3d 20 7a 5b 6a 5d 3b 0a 20 20 7d c = z[j];. }
1730: 0a 20 20 69 66 28 20 63 3d 3d 27 30 27 20 26 26 . if( c=='0' &&
1740: 20 7a 5b 6a 2b 31 5d 3e 3d 27 30 27 20 26 26 20 z[j+1]>='0' &&
1750: 7a 5b 6a 2b 31 5d 3c 3d 27 39 27 20 29 20 72 65 z[j+1]<='9' ) re
1760: 74 75 72 6e 20 30 3b 0a 20 20 66 6f 72 28 3b 3b turn 0;. for(;;
1770: 20 6a 2b 2b 29 7b 0a 20 20 20 20 63 20 3d 20 7a j++){. c = z
1780: 5b 6a 5d 3b 0a 20 20 20 20 69 66 28 20 73 61 66 [j];. if( saf
1790: 65 5f 69 73 64 69 67 69 74 28 63 29 20 29 20 63 e_isdigit(c) ) c
17a0: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 66 28 ontinue;. if(
17b0: 20 63 3d 3d 27 2e 27 20 29 7b 0a 20 20 20 20 20 c=='.' ){.
17c0: 20 69 66 28 20 7a 5b 6a 2d 31 5d 3d 3d 27 2d 27 if( z[j-1]=='-'
17d0: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 ) return 0;.
17e0: 20 20 20 69 66 28 20 73 65 65 6e 44 50 20 29 20 if( seenDP )
17f0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 return 0;.
1800: 73 65 65 6e 44 50 20 3d 20 31 3b 0a 20 20 20 20 seenDP = 1;.
1810: 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 continue;.
1820: 7d 0a 20 20 20 20 69 66 28 20 63 3d 3d 27 65 27 }. if( c=='e'
1830: 20 7c 7c 20 63 3d 3d 27 45 27 20 29 7b 0a 20 20 || c=='E' ){.
1840: 20 20 20 20 69 66 28 20 7a 5b 6a 2d 31 5d 3c 27 if( z[j-1]<'
1850: 30 27 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 0' ) return 0;.
1860: 20 20 20 20 20 69 66 28 20 73 65 65 6e 45 20 29 if( seenE )
1870: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 20 20 return -1;.
1880: 20 20 73 65 65 6e 44 50 20 3d 20 73 65 65 6e 45 seenDP = seenE
1890: 20 3d 20 31 3b 0a 20 20 20 20 20 20 63 20 3d 20 = 1;. c =
18a0: 7a 5b 6a 2b 31 5d 3b 0a 20 20 20 20 20 20 69 66 z[j+1];. if
18b0: 28 20 63 3d 3d 27 2b 27 20 7c 7c 20 63 3d 3d 27 ( c=='+' || c=='
18c0: 2d 27 20 29 7b 0a 20 20 20 20 20 20 20 20 6a 2b -' ){. j+
18d0: 2b 3b 0a 20 20 20 20 20 20 20 20 63 20 3d 20 7a +;. c = z
18e0: 5b 6a 2b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 [j+1];. }.
18f0: 20 20 20 20 20 69 66 28 20 63 3c 27 30 27 20 7c if( c<'0' |
1900: 7c 20 63 3e 27 39 27 20 29 20 72 65 74 75 72 6e | c>'9' ) return
1910: 20 30 3b 0a 20 20 20 20 20 20 63 6f 6e 74 69 6e 0;. contin
1920: 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62 72 ue;. }. br
1930: 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 7a eak;. }. if( z
1940: 5b 6a 2d 31 5d 3c 27 30 27 20 29 20 72 65 74 75 [j-1]<'0' ) retu
1950: 72 6e 20 30 3b 0a 20 20 69 66 28 20 70 56 61 6c rn 0;. if( pVal
1960: 20 29 7b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 ){.#ifdef SQLIT
1970: 45 5f 41 4d 41 4c 47 41 4d 41 54 49 4f 4e 0a 20 E_AMALGAMATION.
1980: 20 20 20 20 2f 2a 20 54 68 65 20 73 71 6c 69 74 /* The sqlit
1990: 65 33 41 74 6f 46 28 29 20 72 6f 75 74 69 6e 65 e3AtoF() routine
19a0: 20 69 73 20 6d 75 63 68 20 6d 75 63 68 20 66 61 is much much fa
19b0: 73 74 65 72 20 74 68 61 6e 20 61 74 6f 66 28 29 ster than atof()
19c0: 2c 20 69 66 20 69 74 0a 20 20 20 20 20 2a 2a 20 , if it. **
19d0: 69 73 20 61 76 61 69 6c 61 62 6c 65 20 2a 2f 0a is available */.
19e0: 20 20 20 20 20 64 6f 75 62 6c 65 20 72 3b 0a 20 double r;.
19f0: 20 20 20 20 28 76 6f 69 64 29 73 71 6c 69 74 65 (void)sqlite
1a00: 33 41 74 6f 46 28 28 63 6f 6e 73 74 20 63 68 61 3AtoF((const cha
1a10: 72 2a 29 70 2d 3e 7a 2c 20 26 72 2c 20 6a 2c 20 r*)p->z, &r, j,
1a20: 53 51 4c 49 54 45 5f 55 54 46 38 29 3b 0a 20 20 SQLITE_UTF8);.
1a30: 20 20 20 2a 70 56 61 6c 20 3d 20 72 3b 0a 23 65 *pVal = r;.#e
1a40: 6c 73 65 0a 20 20 20 20 20 2a 70 56 61 6c 20 3d lse. *pVal =
1a50: 20 28 47 65 6f 43 6f 6f 72 64 29 61 74 6f 66 28 (GeoCoord)atof(
1a60: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 70 2d 3e (const char*)p->
1a70: 7a 29 3b 0a 23 65 6e 64 69 66 0a 20 20 7d 0a 20 z);.#endif. }.
1a80: 20 70 2d 3e 7a 20 2b 3d 20 6a 3b 0a 20 20 72 65 p->z += j;. re
1a90: 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a turn 1;.}../*.**
1aa0: 20 49 66 20 74 68 65 20 69 6e 70 75 74 20 69 73 If the input is
1ab0: 20 61 20 77 65 6c 6c 2d 66 6f 72 6d 65 64 20 4a a well-formed J
1ac0: 53 4f 4e 20 61 72 72 61 79 20 6f 66 20 63 6f 6f SON array of coo
1ad0: 72 64 69 6e 61 74 65 73 20 77 69 74 68 20 61 74 rdinates with at
1ae0: 20 6c 65 61 73 74 0a 2a 2a 20 66 6f 75 72 20 63 least.** four c
1af0: 6f 6f 72 64 69 6e 61 74 65 73 20 61 6e 64 20 77 oordinates and w
1b00: 68 65 72 65 20 65 61 63 68 20 63 6f 6f 72 64 69 here each coordi
1b10: 6e 61 74 65 20 69 73 20 69 74 73 65 6c 66 20 61 nate is itself a
1b20: 20 74 77 6f 2d 76 61 6c 75 65 20 61 72 72 61 79 two-value array
1b30: 2c 0a 2a 2a 20 74 68 65 6e 20 63 6f 6e 76 65 72 ,.** then conver
1b40: 74 20 74 68 65 20 4a 53 4f 4e 20 69 6e 74 6f 20 t the JSON into
1b50: 61 20 47 65 6f 50 6f 6c 79 20 6f 62 6a 65 63 74 a GeoPoly object
1b60: 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 70 6f and return a po
1b70: 69 6e 74 65 72 20 74 6f 0a 2a 2a 20 74 68 61 74 inter to.** that
1b80: 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 49 object..**.** I
1b90: 66 20 61 6e 79 20 65 72 72 6f 72 20 6f 63 63 75 f any error occu
1ba0: 72 73 2c 20 72 65 74 75 72 6e 20 4e 55 4c 4c 2e rs, return NULL.
1bb0: 0a 2a 2f 0a 73 74 61 74 69 63 20 47 65 6f 50 6f .*/.static GeoPo
1bc0: 6c 79 20 2a 67 65 6f 70 6f 6c 79 50 61 72 73 65 ly *geopolyParse
1bd0: 4a 73 6f 6e 28 63 6f 6e 73 74 20 75 6e 73 69 67 Json(const unsig
1be0: 6e 65 64 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74 ned char *z, int
1bf0: 20 2a 70 52 63 29 7b 0a 20 20 47 65 6f 50 61 72 *pRc){. GeoPar
1c00: 73 65 20 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d se s;. int rc =
1c10: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 6d 65 SQLITE_OK;. me
1c20: 6d 73 65 74 28 26 73 2c 20 30 2c 20 73 69 7a 65 mset(&s, 0, size
1c30: 6f 66 28 73 29 29 3b 0a 20 20 73 2e 7a 20 3d 20 of(s));. s.z =
1c40: 7a 3b 0a 20 20 69 66 28 20 67 65 6f 70 6f 6c 79 z;. if( geopoly
1c50: 53 6b 69 70 53 70 61 63 65 28 26 73 29 3d 3d 27 SkipSpace(&s)=='
1c60: 5b 27 20 29 7b 0a 20 20 20 20 73 2e 7a 2b 2b 3b [' ){. s.z++;
1c70: 0a 20 20 20 20 77 68 69 6c 65 28 20 67 65 6f 70 . while( geop
1c80: 6f 6c 79 53 6b 69 70 53 70 61 63 65 28 26 73 29 olySkipSpace(&s)
1c90: 3d 3d 27 5b 27 20 29 7b 0a 20 20 20 20 20 20 69 =='[' ){. i
1ca0: 6e 74 20 69 69 20 3d 20 30 3b 0a 20 20 20 20 20 nt ii = 0;.
1cb0: 20 63 68 61 72 20 63 3b 0a 20 20 20 20 20 20 73 char c;. s
1cc0: 2e 7a 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28 20 .z++;. if(
1cd0: 73 2e 6e 56 65 72 74 65 78 3e 3d 73 2e 6e 41 6c s.nVertex>=s.nAl
1ce0: 6c 6f 63 20 29 7b 0a 20 20 20 20 20 20 20 20 47 loc ){. G
1cf0: 65 6f 43 6f 6f 72 64 20 2a 61 4e 65 77 3b 0a 20 eoCoord *aNew;.
1d00: 20 20 20 20 20 20 20 73 2e 6e 41 6c 6c 6f 63 20 s.nAlloc
1d10: 3d 20 73 2e 6e 41 6c 6c 6f 63 2a 32 20 2b 20 31 = s.nAlloc*2 + 1
1d20: 36 3b 0a 20 20 20 20 20 20 20 20 61 4e 65 77 20 6;. aNew
1d30: 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f = sqlite3_reallo
1d40: 63 36 34 28 73 2e 61 2c 20 73 2e 6e 41 6c 6c 6f c64(s.a, s.nAllo
1d50: 63 2a 73 69 7a 65 6f 66 28 47 65 6f 43 6f 6f 72 c*sizeof(GeoCoor
1d60: 64 29 2a 32 20 29 3b 0a 20 20 20 20 20 20 20 20 d)*2 );.
1d70: 69 66 28 20 61 4e 65 77 3d 3d 30 20 29 7b 0a 20 if( aNew==0 ){.
1d80: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 rc = SQ
1d90: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 LITE_NOMEM;.
1da0: 20 20 20 20 20 20 73 2e 6e 45 72 72 2b 2b 3b 0a s.nErr++;.
1db0: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b break;
1dc0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 . }.
1dd0: 20 20 20 73 2e 61 20 3d 20 61 4e 65 77 3b 0a 20 s.a = aNew;.
1de0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 77 68 69 }. whi
1df0: 6c 65 28 20 67 65 6f 70 6f 6c 79 50 61 72 73 65 le( geopolyParse
1e00: 4e 75 6d 62 65 72 28 26 73 2c 20 69 69 3c 3d 31 Number(&s, ii<=1
1e10: 20 3f 20 26 73 2e 61 5b 73 2e 6e 56 65 72 74 65 ? &s.a[s.nVerte
1e20: 78 2a 32 2b 69 69 5d 20 3a 20 30 29 20 29 7b 0a x*2+ii] : 0) ){.
1e30: 20 20 20 20 20 20 20 20 69 69 2b 2b 3b 0a 20 20 ii++;.
1e40: 20 20 20 20 20 20 69 66 28 20 69 69 3d 3d 32 20 if( ii==2
1e50: 29 20 73 2e 6e 56 65 72 74 65 78 2b 2b 3b 0a 20 ) s.nVertex++;.
1e60: 20 20 20 20 20 20 20 63 20 3d 20 67 65 6f 70 6f c = geopo
1e70: 6c 79 53 6b 69 70 53 70 61 63 65 28 26 73 29 3b lySkipSpace(&s);
1e80: 0a 20 20 20 20 20 20 20 20 73 2e 7a 2b 2b 3b 0a . s.z++;.
1e90: 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27 if( c=='
1ea0: 2c 27 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 ,' ) continue;.
1eb0: 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27 5d if( c==']
1ec0: 27 20 26 26 20 69 69 3e 3d 32 20 29 20 62 72 65 ' && ii>=2 ) bre
1ed0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 73 2e 6e 45 ak;. s.nE
1ee0: 72 72 2b 2b 3b 0a 20 20 20 20 20 20 20 20 72 63 rr++;. rc
1ef0: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b = SQLITE_ERROR;
1f00: 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20 70 61 . goto pa
1f10: 72 73 65 5f 6a 73 6f 6e 5f 65 72 72 3b 0a 20 20 rse_json_err;.
1f20: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 }. if(
1f30: 67 65 6f 70 6f 6c 79 53 6b 69 70 53 70 61 63 65 geopolySkipSpace
1f40: 28 26 73 29 3d 3d 27 2c 27 20 29 7b 0a 20 20 20 (&s)==',' ){.
1f50: 20 20 20 20 20 73 2e 7a 2b 2b 3b 0a 20 20 20 20 s.z++;.
1f60: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 continue;.
1f70: 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 }. brea
1f80: 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 k;. }. if(
1f90: 20 67 65 6f 70 6f 6c 79 53 6b 69 70 53 70 61 63 geopolySkipSpac
1fa0: 65 28 26 73 29 3d 3d 27 5d 27 0a 20 20 20 20 20 e(&s)==']'.
1fb0: 26 26 20 73 2e 6e 56 65 72 74 65 78 3e 3d 34 0a && s.nVertex>=4.
1fc0: 20 20 20 20 20 26 26 20 73 2e 61 5b 30 5d 3d 3d && s.a[0]==
1fd0: 73 2e 61 5b 73 2e 6e 56 65 72 74 65 78 2a 32 2d s.a[s.nVertex*2-
1fe0: 32 5d 0a 20 20 20 20 20 26 26 20 73 2e 61 5b 31 2]. && s.a[1
1ff0: 5d 3d 3d 73 2e 61 5b 73 2e 6e 56 65 72 74 65 78 ]==s.a[s.nVertex
2000: 2a 32 2d 31 5d 0a 20 20 20 20 20 26 26 20 28 73 *2-1]. && (s
2010: 2e 7a 2b 2b 2c 20 67 65 6f 70 6f 6c 79 53 6b 69 .z++, geopolySki
2020: 70 53 70 61 63 65 28 26 73 29 3d 3d 30 29 0a 20 pSpace(&s)==0).
2030: 20 20 20 29 7b 0a 20 20 20 20 20 20 47 65 6f 50 ){. GeoP
2040: 6f 6c 79 20 2a 70 4f 75 74 3b 0a 20 20 20 20 20 oly *pOut;.
2050: 20 69 6e 74 20 78 20 3d 20 31 3b 0a 20 20 20 20 int x = 1;.
2060: 20 20 73 2e 6e 56 65 72 74 65 78 2d 2d 3b 20 20 s.nVertex--;
2070: 2f 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 72 65 /* Remove the re
2080: 64 75 6e 64 61 6e 74 20 76 65 72 74 65 78 20 61 dundant vertex a
2090: 74 20 74 68 65 20 65 6e 64 20 2a 2f 0a 20 20 20 t the end */.
20a0: 20 20 20 70 4f 75 74 20 3d 20 73 71 6c 69 74 65 pOut = sqlite
20b0: 33 5f 6d 61 6c 6c 6f 63 36 34 28 20 47 45 4f 50 3_malloc64( GEOP
20c0: 4f 4c 59 5f 53 5a 28 73 2e 6e 56 65 72 74 65 78 OLY_SZ(s.nVertex
20d0: 29 20 29 3b 0a 20 20 20 20 20 20 78 20 3d 20 31 ) );. x = 1
20e0: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4f 75 74 ;. if( pOut
20f0: 3d 3d 30 20 29 20 67 6f 74 6f 20 70 61 72 73 65 ==0 ) goto parse
2100: 5f 6a 73 6f 6e 5f 65 72 72 3b 0a 20 20 20 20 20 _json_err;.
2110: 20 70 4f 75 74 2d 3e 6e 56 65 72 74 65 78 20 3d pOut->nVertex =
2120: 20 73 2e 6e 56 65 72 74 65 78 3b 0a 20 20 20 20 s.nVertex;.
2130: 20 20 6d 65 6d 63 70 79 28 70 4f 75 74 2d 3e 61 memcpy(pOut->a
2140: 2c 20 73 2e 61 2c 20 73 2e 6e 56 65 72 74 65 78 , s.a, s.nVertex
2150: 2a 32 2a 73 69 7a 65 6f 66 28 47 65 6f 43 6f 6f *2*sizeof(GeoCoo
2160: 72 64 29 29 3b 0a 20 20 20 20 20 20 70 4f 75 74 rd));. pOut
2170: 2d 3e 68 64 72 5b 30 5d 20 3d 20 2a 28 75 6e 73 ->hdr[0] = *(uns
2180: 69 67 6e 65 64 20 63 68 61 72 2a 29 26 78 3b 0a igned char*)&x;.
2190: 20 20 20 20 20 20 70 4f 75 74 2d 3e 68 64 72 5b pOut->hdr[
21a0: 31 5d 20 3d 20 28 73 2e 6e 56 65 72 74 65 78 3e 1] = (s.nVertex>
21b0: 3e 31 36 29 26 30 78 66 66 3b 0a 20 20 20 20 20 >16)&0xff;.
21c0: 20 70 4f 75 74 2d 3e 68 64 72 5b 32 5d 20 3d 20 pOut->hdr[2] =
21d0: 28 73 2e 6e 56 65 72 74 65 78 3e 3e 38 29 26 30 (s.nVertex>>8)&0
21e0: 78 66 66 3b 0a 20 20 20 20 20 20 70 4f 75 74 2d xff;. pOut-
21f0: 3e 68 64 72 5b 33 5d 20 3d 20 73 2e 6e 56 65 72 >hdr[3] = s.nVer
2200: 74 65 78 26 30 78 66 66 3b 0a 20 20 20 20 20 20 tex&0xff;.
2210: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 73 2e 61 sqlite3_free(s.a
2220: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 52 63 );. if( pRc
2230: 20 29 20 2a 70 52 63 20 3d 20 53 51 4c 49 54 45 ) *pRc = SQLITE
2240: 5f 4f 4b 3b 0a 20 20 20 20 20 20 72 65 74 75 72 _OK;. retur
2250: 6e 20 70 4f 75 74 3b 0a 20 20 20 20 7d 65 6c 73 n pOut;. }els
2260: 65 7b 0a 20 20 20 20 20 20 73 2e 6e 45 72 72 2b e{. s.nErr+
2270: 2b 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 +;. rc = SQ
2280: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 LITE_ERROR;.
2290: 7d 0a 20 20 7d 0a 70 61 72 73 65 5f 6a 73 6f 6e }. }.parse_json
22a0: 5f 65 72 72 3a 0a 20 20 69 66 28 20 70 52 63 20 _err:. if( pRc
22b0: 29 20 2a 70 52 63 20 3d 20 72 63 3b 0a 20 20 73 ) *pRc = rc;. s
22c0: 71 6c 69 74 65 33 5f 66 72 65 65 28 73 2e 61 29 qlite3_free(s.a)
22d0: 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a ;. return 0;.}.
22e0: 0a 2f 2a 0a 2a 2a 20 47 69 76 65 6e 20 61 20 66 ./*.** Given a f
22f0: 75 6e 63 74 69 6f 6e 20 70 61 72 61 6d 65 74 65 unction paramete
2300: 72 2c 20 74 72 79 20 74 6f 20 69 6e 74 65 72 70 r, try to interp
2310: 72 65 74 20 69 74 20 61 73 20 61 20 70 6f 6c 79 ret it as a poly
2320: 67 6f 6e 2c 20 65 69 74 68 65 72 0a 2a 2a 20 69 gon, either.** i
2330: 6e 20 74 68 65 20 62 69 6e 61 72 79 20 66 6f 72 n the binary for
2340: 6d 61 74 20 6f 72 20 4a 53 4f 4e 20 74 65 78 74 mat or JSON text
2350: 2e 20 20 43 6f 6d 70 75 74 65 20 61 20 47 65 6f . Compute a Geo
2360: 50 6f 6c 79 20 6f 62 6a 65 63 74 20 61 6e 64 0a Poly object and.
2370: 2a 2a 20 72 65 74 75 72 6e 20 61 20 70 6f 69 6e ** return a poin
2380: 74 65 72 20 74 6f 20 74 68 61 74 20 6f 62 6a 65 ter to that obje
2390: 63 74 2e 20 20 4f 72 20 69 66 20 74 68 65 20 69 ct. Or if the i
23a0: 6e 70 75 74 20 69 73 20 6e 6f 74 20 61 20 77 65 nput is not a we
23b0: 6c 6c 2d 66 6f 72 6d 65 64 0a 2a 2a 20 70 6f 6c ll-formed.** pol
23c0: 79 67 6f 6e 2c 20 70 75 74 20 61 6e 20 65 72 72 ygon, put an err
23d0: 6f 72 20 6d 65 73 73 61 67 65 20 69 6e 20 73 71 or message in sq
23e0: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 61 6e lite3_context an
23f0: 64 20 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 0a 2a d return NULL..*
2400: 2f 0a 73 74 61 74 69 63 20 47 65 6f 50 6f 6c 79 /.static GeoPoly
2410: 20 2a 67 65 6f 70 6f 6c 79 46 75 6e 63 50 61 72 *geopolyFuncPar
2420: 61 6d 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f am(. sqlite3_co
2430: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20 ntext *pCtx,
2440: 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 /* Context for
2450: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 73 20 error messages
2460: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c */. sqlite3_val
2470: 75 65 20 2a 70 56 61 6c 2c 20 20 20 20 20 20 20 ue *pVal,
2480: 20 2f 2a 20 54 68 65 20 76 61 6c 75 65 20 74 6f /* The value to
2490: 20 64 65 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 decode */. int
24a0: 20 2a 70 52 63 20 20 20 20 20 20 20 20 20 20 20 *pRc
24b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 /* Writ
24c0: 65 20 65 72 72 6f 72 20 68 65 72 65 20 2a 2f 0a e error here */.
24d0: 29 7b 0a 20 20 47 65 6f 50 6f 6c 79 20 2a 70 20 ){. GeoPoly *p
24e0: 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 = 0;. int nByte
24f0: 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f ;. if( sqlite3_
2500: 76 61 6c 75 65 5f 74 79 70 65 28 70 56 61 6c 29 value_type(pVal)
2510: 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 0a 20 20 ==SQLITE_BLOB.
2520: 20 26 26 20 28 6e 42 79 74 65 20 3d 20 73 71 6c && (nByte = sql
2530: 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 ite3_value_bytes
2540: 28 70 56 61 6c 29 29 3e 3d 28 34 2b 36 2a 73 69 (pVal))>=(4+6*si
2550: 7a 65 6f 66 28 47 65 6f 43 6f 6f 72 64 29 29 0a zeof(GeoCoord)).
2560: 20 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 75 ){. const u
2570: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 61 20 nsigned char *a
2580: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f = sqlite3_value_
2590: 62 6c 6f 62 28 70 56 61 6c 29 3b 0a 20 20 20 20 blob(pVal);.
25a0: 69 6e 74 20 6e 56 65 72 74 65 78 3b 0a 20 20 20 int nVertex;.
25b0: 20 6e 56 65 72 74 65 78 20 3d 20 28 61 5b 31 5d nVertex = (a[1]
25c0: 3c 3c 31 36 29 20 2b 20 28 61 5b 32 5d 3c 3c 38 <<16) + (a[2]<<8
25d0: 29 20 2b 20 61 5b 33 5d 3b 0a 20 20 20 20 69 66 ) + a[3];. if
25e0: 28 20 28 61 5b 30 5d 3d 3d 30 20 7c 7c 20 61 5b ( (a[0]==0 || a[
25f0: 30 5d 3d 3d 31 29 0a 20 20 20 20 20 26 26 20 28 0]==1). && (
2600: 6e 56 65 72 74 65 78 2a 32 2a 73 69 7a 65 6f 66 nVertex*2*sizeof
2610: 28 47 65 6f 43 6f 6f 72 64 29 20 2b 20 34 29 3d (GeoCoord) + 4)=
2620: 3d 28 75 6e 73 69 67 6e 65 64 20 69 6e 74 29 6e =(unsigned int)n
2630: 42 79 74 65 0a 20 20 20 20 29 7b 0a 20 20 20 20 Byte. ){.
2640: 20 20 70 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 p = sqlite3_ma
2650: 6c 6c 6f 63 36 34 28 20 73 69 7a 65 6f 66 28 2a lloc64( sizeof(*
2660: 70 29 20 2b 20 28 6e 56 65 72 74 65 78 2d 31 29 p) + (nVertex-1)
2670: 2a 32 2a 73 69 7a 65 6f 66 28 47 65 6f 43 6f 6f *2*sizeof(GeoCoo
2680: 72 64 29 20 29 3b 0a 20 20 20 20 20 20 69 66 28 rd) );. if(
2690: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 p==0 ){.
26a0: 20 69 66 28 20 70 52 63 20 29 20 2a 70 52 63 20 if( pRc ) *pRc
26b0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a = SQLITE_NOMEM;.
26c0: 20 20 20 20 20 20 20 20 69 66 28 20 70 43 74 78 if( pCtx
26d0: 20 29 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c ) sqlite3_resul
26e0: 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 6d 28 70 43 t_error_nomem(pC
26f0: 74 78 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 tx);. }else
2700: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 78 20 {. int x
2710: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e = 1;. p->
2720: 6e 56 65 72 74 65 78 20 3d 20 6e 56 65 72 74 65 nVertex = nVerte
2730: 78 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 x;. memcp
2740: 79 28 70 2d 3e 68 64 72 2c 20 61 2c 20 6e 42 79 y(p->hdr, a, nBy
2750: 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 te);. if(
2760: 20 61 5b 30 5d 20 21 3d 20 2a 28 75 6e 73 69 67 a[0] != *(unsig
2770: 6e 65 64 20 63 68 61 72 2a 29 26 78 20 29 7b 0a ned char*)&x ){.
2780: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 69 int ii
2790: 3b 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 ;. for(
27a0: 69 69 3d 30 3b 20 69 69 3c 6e 56 65 72 74 65 78 ii=0; ii<nVertex
27b0: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 ; ii++){.
27c0: 20 20 20 20 20 67 65 6f 70 6f 6c 79 53 77 61 62 geopolySwab
27d0: 33 32 28 28 75 6e 73 69 67 6e 65 64 20 63 68 61 32((unsigned cha
27e0: 72 2a 29 26 47 65 6f 58 28 70 2c 69 69 29 29 3b r*)&GeoX(p,ii));
27f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 67 65 6f . geo
2800: 70 6f 6c 79 53 77 61 62 33 32 28 28 75 6e 73 69 polySwab32((unsi
2810: 67 6e 65 64 20 63 68 61 72 2a 29 26 47 65 6f 59 gned char*)&GeoY
2820: 28 70 2c 69 69 29 29 3b 0a 20 20 20 20 20 20 20 (p,ii));.
2830: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 70 }. p
2840: 2d 3e 68 64 72 5b 30 5d 20 5e 3d 20 31 3b 0a 20 ->hdr[0] ^= 1;.
2850: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d }. }
2860: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 . }. if( p
2870: 52 63 20 29 20 2a 70 52 63 20 3d 20 53 51 4c 49 Rc ) *pRc = SQLI
2880: 54 45 5f 4f 4b 3b 0a 20 20 20 20 72 65 74 75 72 TE_OK;. retur
2890: 6e 20 70 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 n p;. }else if(
28a0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 sqlite3_value_t
28b0: 79 70 65 28 70 56 61 6c 29 3d 3d 53 51 4c 49 54 ype(pVal)==SQLIT
28c0: 45 5f 54 45 58 54 20 29 7b 0a 20 20 20 20 63 6f E_TEXT ){. co
28d0: 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 nst unsigned cha
28e0: 72 20 2a 7a 4a 73 6f 6e 20 3d 20 73 71 6c 69 74 r *zJson = sqlit
28f0: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 56 e3_value_text(pV
2900: 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 7a 4a 73 al);. if( zJs
2910: 6f 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 on==0 ){. i
2920: 66 28 20 70 52 63 20 29 20 2a 70 52 63 20 3d 20 f( pRc ) *pRc =
2930: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 SQLITE_NOMEM;.
2940: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 return 0;.
2950: 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 67 }. return g
2960: 65 6f 70 6f 6c 79 50 61 72 73 65 4a 73 6f 6e 28 eopolyParseJson(
2970: 7a 4a 73 6f 6e 2c 20 70 52 63 29 3b 0a 20 20 7d zJson, pRc);. }
2980: 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 70 52 else{. if( pR
2990: 63 20 29 20 2a 70 52 63 20 3d 20 53 51 4c 49 54 c ) *pRc = SQLIT
29a0: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 72 65 74 E_ERROR;. ret
29b0: 75 72 6e 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a urn 0;. }.}../*
29c0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 .** Implementati
29d0: 6f 6e 20 6f 66 20 74 68 65 20 67 65 6f 70 6f 6c on of the geopol
29e0: 79 5f 62 6c 6f 62 28 58 29 20 66 75 6e 63 74 69 y_blob(X) functi
29f0: 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 on..**.** If the
2a00: 20 69 6e 70 75 74 20 69 73 20 61 20 77 65 6c 6c input is a well
2a10: 2d 66 6f 72 6d 65 64 20 47 65 6f 70 6f 6c 79 20 -formed Geopoly
2a20: 42 4c 4f 42 20 6f 72 20 4a 53 4f 4e 20 73 74 72 BLOB or JSON str
2a30: 69 6e 67 0a 2a 2a 20 74 68 65 6e 20 72 65 74 75 ing.** then retu
2a40: 72 6e 20 74 68 65 20 42 4c 4f 42 20 72 65 70 72 rn the BLOB repr
2a50: 65 73 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 esentation of th
2a60: 65 20 70 6f 6c 79 67 6f 6e 2e 20 20 4f 74 68 65 e polygon. Othe
2a70: 72 77 69 73 65 0a 2a 2a 20 72 65 74 75 72 6e 20 rwise.** return
2a80: 4e 55 4c 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 NULL..*/.static
2a90: 76 6f 69 64 20 67 65 6f 70 6f 6c 79 42 6c 6f 62 void geopolyBlob
2aa0: 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f Func(. sqlite3_
2ab0: 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 context *context
2ac0: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 ,. int argc,.
2ad0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a sqlite3_value **
2ae0: 61 72 67 76 0a 29 7b 0a 20 20 47 65 6f 50 6f 6c argv.){. GeoPol
2af0: 79 20 2a 70 20 3d 20 67 65 6f 70 6f 6c 79 46 75 y *p = geopolyFu
2b00: 6e 63 50 61 72 61 6d 28 63 6f 6e 74 65 78 74 2c ncParam(context,
2b10: 20 61 72 67 76 5b 30 5d 2c 20 30 29 3b 0a 20 20 argv[0], 0);.
2b20: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 73 71 6c if( p ){. sql
2b30: 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 ite3_result_blob
2b40: 28 63 6f 6e 74 65 78 74 2c 20 70 2d 3e 68 64 72 (context, p->hdr
2b50: 2c 20 0a 20 20 20 20 20 20 20 34 2b 38 2a 70 2d , . 4+8*p-
2b60: 3e 6e 56 65 72 74 65 78 2c 20 53 51 4c 49 54 45 >nVertex, SQLITE
2b70: 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 _TRANSIENT);.
2b80: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 sqlite3_free(p)
2b90: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 ;. }.}../*.** S
2ba0: 51 4c 20 66 75 6e 63 74 69 6f 6e 3a 20 20 20 20 QL function:
2bb0: 20 67 65 6f 70 6f 6c 79 5f 6a 73 6f 6e 28 58 29 geopoly_json(X)
2bc0: 0a 2a 2a 0a 2a 2a 20 49 6e 74 65 72 70 72 65 74 .**.** Interpret
2bd0: 20 58 20 61 73 20 61 20 70 6f 6c 79 67 6f 6e 20 X as a polygon
2be0: 61 6e 64 20 72 65 6e 64 65 72 20 69 74 20 61 73 and render it as
2bf0: 20 61 20 4a 53 4f 4e 20 61 72 72 61 79 0a 2a 2a a JSON array.**
2c00: 20 6f 66 20 63 6f 6f 72 64 69 6e 61 74 65 73 2e of coordinates.
2c10: 20 20 4f 72 2c 20 69 66 20 58 20 69 73 20 6e 6f Or, if X is no
2c20: 74 20 61 20 76 61 6c 69 64 20 70 6f 6c 79 67 6f t a valid polygo
2c30: 6e 2c 20 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 0a n, return NULL..
2c40: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 67 */.static void g
2c50: 65 6f 70 6f 6c 79 4a 73 6f 6e 46 75 6e 63 28 0a eopolyJsonFunc(.
2c60: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 sqlite3_contex
2c70: 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e t *context,. in
2c80: 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 t argc,. sqlite
2c90: 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 3_value **argv.)
2ca0: 7b 0a 20 20 47 65 6f 50 6f 6c 79 20 2a 70 20 3d {. GeoPoly *p =
2cb0: 20 67 65 6f 70 6f 6c 79 46 75 6e 63 50 61 72 61 geopolyFuncPara
2cc0: 6d 28 63 6f 6e 74 65 78 74 2c 20 61 72 67 76 5b m(context, argv[
2cd0: 30 5d 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 20 0], 0);. if( p
2ce0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 20 2a ){. sqlite3 *
2cf0: 64 62 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6e db = sqlite3_con
2d00: 74 65 78 74 5f 64 62 5f 68 61 6e 64 6c 65 28 63 text_db_handle(c
2d10: 6f 6e 74 65 78 74 29 3b 0a 20 20 20 20 73 71 6c ontext);. sql
2d20: 69 74 65 33 5f 73 74 72 20 2a 78 20 3d 20 73 71 ite3_str *x = sq
2d30: 6c 69 74 65 33 5f 73 74 72 5f 6e 65 77 28 64 62 lite3_str_new(db
2d40: 29 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 );. int i;.
2d50: 20 20 73 71 6c 69 74 65 33 5f 73 74 72 5f 61 70 sqlite3_str_ap
2d60: 70 65 6e 64 28 78 2c 20 22 5b 22 2c 20 31 29 3b pend(x, "[", 1);
2d70: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c . for(i=0; i<
2d80: 70 2d 3e 6e 56 65 72 74 65 78 3b 20 69 2b 2b 29 p->nVertex; i++)
2d90: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f {. sqlite3_
2da0: 73 74 72 5f 61 70 70 65 6e 64 66 28 78 2c 20 22 str_appendf(x, "
2db0: 5b 25 21 67 2c 25 21 67 5d 2c 22 2c 20 47 65 6f [%!g,%!g],", Geo
2dc0: 58 28 70 2c 69 29 2c 20 47 65 6f 59 28 70 2c 69 X(p,i), GeoY(p,i
2dd0: 29 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 ));. }. sq
2de0: 6c 69 74 65 33 5f 73 74 72 5f 61 70 70 65 6e 64 lite3_str_append
2df0: 66 28 78 2c 20 22 5b 25 21 67 2c 25 21 67 5d 5d f(x, "[%!g,%!g]]
2e00: 22 2c 20 47 65 6f 58 28 70 2c 30 29 2c 20 47 65 ", GeoX(p,0), Ge
2e10: 6f 59 28 70 2c 30 29 29 3b 0a 20 20 20 20 73 71 oY(p,0));. sq
2e20: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 lite3_result_tex
2e30: 74 28 63 6f 6e 74 65 78 74 2c 20 73 71 6c 69 74 t(context, sqlit
2e40: 65 33 5f 73 74 72 5f 66 69 6e 69 73 68 28 78 29 e3_str_finish(x)
2e50: 2c 20 2d 31 2c 20 73 71 6c 69 74 65 33 5f 66 72 , -1, sqlite3_fr
2e60: 65 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 ee);. sqlite3
2e70: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a _free(p);. }.}.
2e80: 0a 2f 2a 0a 2a 2a 20 53 51 4c 20 66 75 6e 63 74 ./*.** SQL funct
2e90: 69 6f 6e 3a 20 20 20 20 20 67 65 6f 70 6f 6c 79 ion: geopoly
2ea0: 5f 73 76 67 28 58 2c 20 2e 2e 2e 2e 29 0a 2a 2a _svg(X, ....).**
2eb0: 0a 2a 2a 20 49 6e 74 65 72 70 72 65 74 20 58 20 .** Interpret X
2ec0: 61 73 20 61 20 70 6f 6c 79 67 6f 6e 20 61 6e 64 as a polygon and
2ed0: 20 72 65 6e 64 65 72 20 69 74 20 61 73 20 61 20 render it as a
2ee0: 53 56 47 20 3c 70 6f 6c 79 6c 69 6e 65 3e 2e 0a SVG <polyline>..
2ef0: 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c 20 61 72 ** Additional ar
2f00: 67 75 6d 65 6e 74 73 20 61 72 65 20 61 64 64 65 guments are adde
2f10: 64 20 61 73 20 61 74 74 72 69 62 75 74 65 73 20 d as attributes
2f20: 74 6f 20 74 68 65 20 3c 70 6f 6c 79 6c 69 6e 65 to the <polyline
2f30: 3e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 >..*/.static voi
2f40: 64 20 67 65 6f 70 6f 6c 79 53 76 67 46 75 6e 63 d geopolySvgFunc
2f50: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 (. sqlite3_cont
2f60: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 ext *context,.
2f70: 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 int argc,. sqli
2f80: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 te3_value **argv
2f90: 0a 29 7b 0a 20 20 47 65 6f 50 6f 6c 79 20 2a 70 .){. GeoPoly *p
2fa0: 3b 0a 20 20 69 66 28 20 61 72 67 63 3c 31 20 29 ;. if( argc<1 )
2fb0: 20 72 65 74 75 72 6e 3b 0a 20 20 70 20 3d 20 67 return;. p = g
2fc0: 65 6f 70 6f 6c 79 46 75 6e 63 50 61 72 61 6d 28 eopolyFuncParam(
2fd0: 63 6f 6e 74 65 78 74 2c 20 61 72 67 76 5b 30 5d context, argv[0]
2fe0: 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 20 29 7b , 0);. if( p ){
2ff0: 0a 20 20 20 20 73 71 6c 69 74 65 33 20 2a 64 62 . sqlite3 *db
3000: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 = sqlite3_conte
3010: 78 74 5f 64 62 5f 68 61 6e 64 6c 65 28 63 6f 6e xt_db_handle(con
3020: 74 65 78 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 text);. sqlit
3030: 65 33 5f 73 74 72 20 2a 78 20 3d 20 73 71 6c 69 e3_str *x = sqli
3040: 74 65 33 5f 73 74 72 5f 6e 65 77 28 64 62 29 3b te3_str_new(db);
3050: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 . int i;.
3060: 63 68 61 72 20 63 53 65 70 20 3d 20 27 5c 27 27 char cSep = '\''
3070: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 ;. sqlite3_st
3080: 72 5f 61 70 70 65 6e 64 66 28 78 2c 20 22 3c 70 r_appendf(x, "<p
3090: 6f 6c 79 6c 69 6e 65 20 70 6f 69 6e 74 73 3d 22 olyline points="
30a0: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 );. for(i=0;
30b0: 69 3c 70 2d 3e 6e 56 65 72 74 65 78 3b 20 69 2b i<p->nVertex; i+
30c0: 2b 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 +){. sqlite
30d0: 33 5f 73 74 72 5f 61 70 70 65 6e 64 66 28 78 2c 3_str_appendf(x,
30e0: 20 22 25 63 25 67 2c 25 67 22 2c 20 63 53 65 70 "%c%g,%g", cSep
30f0: 2c 20 47 65 6f 58 28 70 2c 69 29 2c 20 47 65 6f , GeoX(p,i), Geo
3100: 59 28 70 2c 69 29 29 3b 0a 20 20 20 20 20 20 63 Y(p,i));. c
3110: 53 65 70 20 3d 20 27 20 27 3b 0a 20 20 20 20 7d Sep = ' ';. }
3120: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 72 . sqlite3_str
3130: 5f 61 70 70 65 6e 64 66 28 78 2c 20 22 20 25 67 _appendf(x, " %g
3140: 2c 25 67 27 22 2c 20 47 65 6f 58 28 70 2c 30 29 ,%g'", GeoX(p,0)
3150: 2c 20 47 65 6f 59 28 70 2c 30 29 29 3b 0a 20 20 , GeoY(p,0));.
3160: 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 61 72 67 for(i=1; i<arg
3170: 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 c; i++){. c
3180: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 28 onst char *z = (
3190: 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 const char*)sqli
31a0: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 te3_value_text(a
31b0: 72 67 76 5b 69 5d 29 3b 0a 20 20 20 20 20 20 69 rgv[i]);. i
31c0: 66 28 20 7a 20 26 26 20 7a 5b 30 5d 20 29 7b 0a f( z && z[0] ){.
31d0: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f sqlite3_
31e0: 73 74 72 5f 61 70 70 65 6e 64 66 28 78 2c 20 22 str_appendf(x, "
31f0: 20 25 73 22 2c 20 7a 29 3b 0a 20 20 20 20 20 20 %s", z);.
3200: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 }. }. sqli
3210: 74 65 33 5f 73 74 72 5f 61 70 70 65 6e 64 66 28 te3_str_appendf(
3220: 78 2c 20 22 3e 3c 2f 70 6f 6c 79 6c 69 6e 65 3e x, "></polyline>
3230: 22 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f ");. sqlite3_
3240: 72 65 73 75 6c 74 5f 74 65 78 74 28 63 6f 6e 74 result_text(cont
3250: 65 78 74 2c 20 73 71 6c 69 74 65 33 5f 73 74 72 ext, sqlite3_str
3260: 5f 66 69 6e 69 73 68 28 78 29 2c 20 2d 31 2c 20 _finish(x), -1,
3270: 73 71 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 sqlite3_free);.
3280: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 sqlite3_free(
3290: 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a p);. }.}../*.**
32a0: 20 53 51 4c 20 46 75 6e 63 74 69 6f 6e 3a 20 20 SQL Function:
32b0: 20 20 20 20 67 65 6f 70 6f 6c 79 5f 78 66 6f 72 geopoly_xfor
32c0: 6d 28 70 6f 6c 79 2c 20 41 2c 20 42 2c 20 43 2c m(poly, A, B, C,
32d0: 20 44 2c 20 45 2c 20 46 29 0a 2a 2a 0a 2a 2a 20 D, E, F).**.**
32e0: 54 72 61 6e 73 66 6f 72 6d 20 61 6e 64 2f 6f 72 Transform and/or
32f0: 20 74 72 61 6e 73 6c 61 74 65 20 61 20 70 6f 6c translate a pol
3300: 79 67 6f 6e 20 61 73 20 66 6f 6c 6c 6f 77 73 3a ygon as follows:
3310: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 78 31 20 3d .**.** x1 =
3320: 20 41 2a 78 30 20 2b 20 42 2a 79 30 20 2b 20 45 A*x0 + B*y0 + E
3330: 0a 2a 2a 20 20 20 20 20 20 79 31 20 3d 20 43 2a .** y1 = C*
3340: 78 30 20 2b 20 44 2a 79 30 20 2b 20 46 0a 2a 2a x0 + D*y0 + F.**
3350: 0a 2a 2a 20 46 6f 72 20 61 20 74 72 61 6e 73 6c .** For a transl
3360: 61 74 69 6f 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 ation:.**.**
3370: 20 20 67 65 6f 70 6f 6c 79 5f 78 66 6f 72 6d 28 geopoly_xform(
3380: 70 6f 6c 79 2c 20 31 2c 20 30 2c 20 30 2c 20 31 poly, 1, 0, 0, 1
3390: 2c 20 78 2d 6f 66 66 73 65 74 2c 20 79 2d 6f 66 , x-offset, y-of
33a0: 66 73 65 74 29 0a 2a 2a 0a 2a 2a 20 52 6f 74 61 fset).**.** Rota
33b0: 74 65 20 62 79 20 52 20 61 72 6f 75 6e 64 20 74 te by R around t
33c0: 68 65 20 70 6f 69 6e 74 20 28 30 2c 30 29 3a 0a he point (0,0):.
33d0: 2a 2a 0a 2a 2a 20 20 20 20 20 20 67 65 6f 70 6f **.** geopo
33e0: 6c 79 5f 78 66 6f 72 6d 28 70 6f 6c 79 2c 20 63 ly_xform(poly, c
33f0: 6f 73 28 52 29 2c 20 73 69 6e 28 52 29 2c 20 2d os(R), sin(R), -
3400: 73 69 6e 28 52 29 2c 20 63 6f 73 28 52 29 2c 20 sin(R), cos(R),
3410: 30 2c 20 30 29 0a 2a 2f 0a 73 74 61 74 69 63 20 0, 0).*/.static
3420: 76 6f 69 64 20 67 65 6f 70 6f 6c 79 58 66 6f 72 void geopolyXfor
3430: 6d 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 mFunc(. sqlite3
3440: 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 _context *contex
3450: 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 t,. int argc,.
3460: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a sqlite3_value *
3470: 2a 61 72 67 76 0a 29 7b 0a 20 20 47 65 6f 50 6f *argv.){. GeoPo
3480: 6c 79 20 2a 70 20 3d 20 67 65 6f 70 6f 6c 79 46 ly *p = geopolyF
3490: 75 6e 63 50 61 72 61 6d 28 63 6f 6e 74 65 78 74 uncParam(context
34a0: 2c 20 61 72 67 76 5b 30 5d 2c 20 30 29 3b 0a 20 , argv[0], 0);.
34b0: 20 64 6f 75 62 6c 65 20 41 20 3d 20 73 71 6c 69 double A = sqli
34c0: 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75 62 6c 65 te3_value_double
34d0: 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20 64 6f 75 (argv[1]);. dou
34e0: 62 6c 65 20 42 20 3d 20 73 71 6c 69 74 65 33 5f ble B = sqlite3_
34f0: 76 61 6c 75 65 5f 64 6f 75 62 6c 65 28 61 72 67 value_double(arg
3500: 76 5b 32 5d 29 3b 0a 20 20 64 6f 75 62 6c 65 20 v[2]);. double
3510: 43 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 C = sqlite3_valu
3520: 65 5f 64 6f 75 62 6c 65 28 61 72 67 76 5b 33 5d e_double(argv[3]
3530: 29 3b 0a 20 20 64 6f 75 62 6c 65 20 44 20 3d 20 );. double D =
3540: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f sqlite3_value_do
3550: 75 62 6c 65 28 61 72 67 76 5b 34 5d 29 3b 0a 20 uble(argv[4]);.
3560: 20 64 6f 75 62 6c 65 20 45 20 3d 20 73 71 6c 69 double E = sqli
3570: 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75 62 6c 65 te3_value_double
3580: 28 61 72 67 76 5b 35 5d 29 3b 0a 20 20 64 6f 75 (argv[5]);. dou
3590: 62 6c 65 20 46 20 3d 20 73 71 6c 69 74 65 33 5f ble F = sqlite3_
35a0: 76 61 6c 75 65 5f 64 6f 75 62 6c 65 28 61 72 67 value_double(arg
35b0: 76 5b 36 5d 29 3b 0a 20 20 47 65 6f 43 6f 6f 72 v[6]);. GeoCoor
35c0: 64 20 78 31 2c 20 79 31 2c 20 78 30 2c 20 79 30 d x1, y1, x0, y0
35d0: 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 69 66 ;. int ii;. if
35e0: 28 20 70 20 29 7b 0a 20 20 20 20 66 6f 72 28 69 ( p ){. for(i
35f0: 69 3d 30 3b 20 69 69 3c 70 2d 3e 6e 56 65 72 74 i=0; ii<p->nVert
3600: 65 78 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 ex; ii++){.
3610: 20 78 30 20 3d 20 47 65 6f 58 28 70 2c 69 69 29 x0 = GeoX(p,ii)
3620: 3b 0a 20 20 20 20 20 20 79 30 20 3d 20 47 65 6f ;. y0 = Geo
3630: 59 28 70 2c 69 69 29 3b 0a 20 20 20 20 20 20 78 Y(p,ii);. x
3640: 31 20 3d 20 28 47 65 6f 43 6f 6f 72 64 29 28 41 1 = (GeoCoord)(A
3650: 2a 78 30 20 2b 20 42 2a 79 30 20 2b 20 45 29 3b *x0 + B*y0 + E);
3660: 0a 20 20 20 20 20 20 79 31 20 3d 20 28 47 65 6f . y1 = (Geo
3670: 43 6f 6f 72 64 29 28 43 2a 78 30 20 2b 20 44 2a Coord)(C*x0 + D*
3680: 79 30 20 2b 20 46 29 3b 0a 20 20 20 20 20 20 47 y0 + F);. G
3690: 65 6f 58 28 70 2c 69 69 29 20 3d 20 78 31 3b 0a eoX(p,ii) = x1;.
36a0: 20 20 20 20 20 20 47 65 6f 59 28 70 2c 69 69 29 GeoY(p,ii)
36b0: 20 3d 20 79 31 3b 0a 20 20 20 20 7d 0a 20 20 20 = y1;. }.
36c0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f sqlite3_result_
36d0: 62 6c 6f 62 28 63 6f 6e 74 65 78 74 2c 20 70 2d blob(context, p-
36e0: 3e 68 64 72 2c 20 0a 20 20 20 20 20 20 20 34 2b >hdr, . 4+
36f0: 38 2a 70 2d 3e 6e 56 65 72 74 65 78 2c 20 53 51 8*p->nVertex, SQ
3700: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b LITE_TRANSIENT);
3710: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 . sqlite3_fre
3720: 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a e(p);. }.}../*.
3730: 2a 2a 20 43 6f 6d 70 75 74 65 20 74 68 65 20 61 ** Compute the a
3740: 72 65 61 20 65 6e 63 6c 6f 73 65 64 20 62 79 20 rea enclosed by
3750: 74 68 65 20 70 6f 6c 79 67 6f 6e 2e 0a 2a 2a 0a the polygon..**.
3760: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 ** This routine
3770: 63 61 6e 20 61 6c 73 6f 20 62 65 20 75 73 65 64 can also be used
3780: 20 74 6f 20 64 65 74 65 63 74 20 70 6f 6c 79 67 to detect polyg
3790: 6f 6e 73 20 74 68 61 74 20 72 6f 74 61 74 65 20 ons that rotate
37a0: 69 6e 0a 2a 2a 20 74 68 65 20 77 72 6f 6e 67 20 in.** the wrong
37b0: 64 69 72 65 63 74 69 6f 6e 2e 20 20 50 6f 6c 79 direction. Poly
37c0: 67 6f 6e 73 20 61 72 65 20 73 75 70 70 6f 73 65 gons are suppose
37d0: 20 74 6f 20 62 65 20 63 6f 75 6e 74 65 72 2d 63 to be counter-c
37e0: 6c 6f 63 6b 77 69 73 65 20 28 43 43 57 29 2e 0a lockwise (CCW)..
37f0: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 ** This routine
3800: 72 65 74 75 72 6e 73 20 61 20 6e 65 67 61 74 69 returns a negati
3810: 76 65 20 76 61 6c 75 65 20 66 6f 72 20 63 6c 6f ve value for clo
3820: 63 6b 77 69 73 65 20 28 43 57 29 20 70 6f 6c 79 ckwise (CW) poly
3830: 67 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 gons..*/.static
3840: 64 6f 75 62 6c 65 20 67 65 6f 70 6f 6c 79 41 72 double geopolyAr
3850: 65 61 28 47 65 6f 50 6f 6c 79 20 2a 70 29 7b 0a ea(GeoPoly *p){.
3860: 20 20 64 6f 75 62 6c 65 20 72 41 72 65 61 20 3d double rArea =
3870: 20 30 2e 30 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 0.0;. int ii;.
3880: 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 for(ii=0; ii<p
3890: 2d 3e 6e 56 65 72 74 65 78 2d 31 3b 20 69 69 2b ->nVertex-1; ii+
38a0: 2b 29 7b 0a 20 20 20 20 72 41 72 65 61 20 2b 3d +){. rArea +=
38b0: 20 28 47 65 6f 58 28 70 2c 69 69 29 20 2d 20 47 (GeoX(p,ii) - G
38c0: 65 6f 58 28 70 2c 69 69 2b 31 29 29 20 20 20 20 eoX(p,ii+1))
38d0: 20 20 20 20 20 20 20 2f 2a 20 28 78 30 20 2d 20 /* (x0 -
38e0: 78 31 29 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 x1) */.
38f0: 20 20 20 20 20 2a 20 28 47 65 6f 59 28 70 2c 69 * (GeoY(p,i
3900: 69 29 20 2b 20 47 65 6f 59 28 70 2c 69 69 2b 31 i) + GeoY(p,ii+1
3910: 29 29 20 20 20 20 20 20 20 20 2f 2a 20 28 79 30 )) /* (y0
3920: 20 2b 20 79 31 29 20 2a 2f 0a 20 20 20 20 20 20 + y1) */.
3930: 20 20 20 20 20 20 20 20 2a 20 30 2e 35 3b 0a 20 * 0.5;.
3940: 20 7d 0a 20 20 72 41 72 65 61 20 2b 3d 20 28 47 }. rArea += (G
3950: 65 6f 58 28 70 2c 69 69 29 20 2d 20 47 65 6f 58 eoX(p,ii) - GeoX
3960: 28 70 2c 30 29 29 20 20 20 20 20 20 20 20 20 20 (p,0))
3970: 20 20 20 20 20 20 2f 2a 20 28 78 4e 20 2d 20 78 /* (xN - x
3980: 30 29 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 0) */.
3990: 20 2a 20 28 47 65 6f 59 28 70 2c 69 69 29 20 2b * (GeoY(p,ii) +
39a0: 20 47 65 6f 59 28 70 2c 30 29 29 20 20 20 20 20 GeoY(p,0))
39b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 28 79 4e 20 /* (yN
39c0: 2b 20 79 30 29 20 2a 2f 0a 20 20 20 20 20 20 20 + y0) */.
39d0: 20 20 20 20 2a 20 30 2e 35 3b 0a 20 20 72 65 74 * 0.5;. ret
39e0: 75 72 6e 20 72 41 72 65 61 3b 0a 7d 0a 0a 2f 2a urn rArea;.}../*
39f0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 .** Implementati
3a00: 6f 6e 20 6f 66 20 74 68 65 20 67 65 6f 70 6f 6c on of the geopol
3a10: 79 5f 61 72 65 61 28 58 29 20 66 75 6e 63 74 69 y_area(X) functi
3a20: 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 on..**.** If the
3a30: 20 69 6e 70 75 74 20 69 73 20 61 20 77 65 6c 6c input is a well
3a40: 2d 66 6f 72 6d 65 64 20 47 65 6f 70 6f 6c 79 20 -formed Geopoly
3a50: 42 4c 4f 42 20 74 68 65 6e 20 72 65 74 75 72 6e BLOB then return
3a60: 20 74 68 65 20 61 72 65 61 0a 2a 2a 20 65 6e 63 the area.** enc
3a70: 6c 6f 73 65 64 20 62 79 20 74 68 65 20 70 6f 6c losed by the pol
3a80: 79 67 6f 6e 2e 20 20 49 66 20 74 68 65 20 70 6f ygon. If the po
3a90: 6c 79 67 6f 6e 20 63 69 72 63 75 6c 61 74 65 73 lygon circulates
3aa0: 20 63 6c 6f 63 6b 77 69 73 65 20 69 6e 73 74 65 clockwise inste
3ab0: 61 64 0a 2a 2a 20 6f 66 20 63 6f 75 6e 74 65 72 ad.** of counter
3ac0: 63 6c 6f 63 6b 77 69 73 65 20 28 61 73 20 69 74 clockwise (as it
3ad0: 20 73 68 6f 75 6c 64 29 20 74 68 65 6e 20 72 65 should) then re
3ae0: 74 75 72 6e 20 74 68 65 20 6e 65 67 61 74 69 76 turn the negativ
3af0: 65 20 6f 66 20 74 68 65 0a 2a 2a 20 65 6e 63 6c e of the.** encl
3b00: 6f 73 65 64 20 61 72 65 61 2e 20 20 4f 74 68 65 osed area. Othe
3b10: 72 77 69 73 65 20 72 65 74 75 72 6e 20 4e 55 4c rwise return NUL
3b20: 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 L..*/.static voi
3b30: 64 20 67 65 6f 70 6f 6c 79 41 72 65 61 46 75 6e d geopolyAreaFun
3b40: 63 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e c(. sqlite3_con
3b50: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 text *context,.
3b60: 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c int argc,. sql
3b70: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 ite3_value **arg
3b80: 76 0a 29 7b 0a 20 20 47 65 6f 50 6f 6c 79 20 2a v.){. GeoPoly *
3b90: 70 20 3d 20 67 65 6f 70 6f 6c 79 46 75 6e 63 50 p = geopolyFuncP
3ba0: 61 72 61 6d 28 63 6f 6e 74 65 78 74 2c 20 61 72 aram(context, ar
3bb0: 67 76 5b 30 5d 2c 20 30 29 3b 0a 20 20 69 66 28 gv[0], 0);. if(
3bc0: 20 70 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 p ){. sqlite
3bd0: 33 5f 72 65 73 75 6c 74 5f 64 6f 75 62 6c 65 28 3_result_double(
3be0: 63 6f 6e 74 65 78 74 2c 20 67 65 6f 70 6f 6c 79 context, geopoly
3bf0: 41 72 65 61 28 70 29 29 3b 0a 20 20 20 20 73 71 Area(p));. sq
3c00: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 lite3_free(p);.
3c10: 20 7d 20 20 20 20 20 20 20 20 20 20 20 20 0a 7d } .}
3c20: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e ../*.** Implemen
3c30: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 67 65 tation of the ge
3c40: 6f 70 6f 6c 79 5f 63 63 77 28 58 29 20 66 75 6e opoly_ccw(X) fun
3c50: 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 ction..**.** If
3c60: 74 68 65 20 72 6f 74 61 74 69 6f 6e 20 6f 66 20 the rotation of
3c70: 70 6f 6c 79 67 6f 6e 20 58 20 69 73 20 63 6c 6f polygon X is clo
3c80: 63 6b 77 69 73 65 20 28 69 6e 63 6f 72 72 65 63 ckwise (incorrec
3c90: 74 29 20 69 6e 73 74 65 61 64 20 6f 66 0a 2a 2a t) instead of.**
3ca0: 20 63 6f 75 6e 74 65 72 2d 63 6c 6f 63 6b 77 69 counter-clockwi
3cb0: 73 65 20 28 74 68 65 20 63 6f 72 72 65 63 74 20 se (the correct
3cc0: 77 69 6e 64 69 6e 67 20 6f 72 64 65 72 20 61 63 winding order ac
3cd0: 63 6f 72 64 69 6e 67 20 74 6f 20 52 46 43 37 39 cording to RFC79
3ce0: 34 36 29 0a 2a 2a 20 74 68 65 6e 20 72 65 76 65 46).** then reve
3cf0: 72 73 65 20 74 68 65 20 6f 72 64 65 72 20 6f 66 rse the order of
3d00: 20 74 68 65 20 76 65 72 74 65 78 65 73 20 69 6e the vertexes in
3d10: 20 70 6f 6c 79 67 6f 6e 20 58 2e 20 20 0a 2a 2a polygon X. .**
3d20: 0a 2a 2a 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 .** In other wor
3d30: 64 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 ds, this routine
3d40: 20 72 65 74 75 72 6e 73 20 61 20 43 43 57 20 70 returns a CCW p
3d50: 6f 6c 79 67 6f 6e 20 72 65 67 61 72 64 6c 65 73 olygon regardles
3d60: 73 20 6f 66 20 74 68 65 0a 2a 2a 20 77 69 6e 64 s of the.** wind
3d70: 69 6e 67 20 6f 72 64 65 72 20 6f 66 20 69 74 73 ing order of its
3d80: 20 69 6e 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 55 73 input..**.** Us
3d90: 65 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 74 e this routine t
3da0: 6f 20 73 61 6e 69 74 69 7a 65 20 68 69 73 74 6f o sanitize histo
3db0: 72 69 63 61 6c 20 69 6e 70 75 74 73 20 74 68 61 rical inputs tha
3dc0: 74 20 74 68 61 74 20 73 6f 6d 65 74 69 6d 65 73 t that sometimes
3dd0: 0a 2a 2a 20 63 6f 6e 74 61 69 6e 20 70 6f 6c 79 .** contain poly
3de0: 67 6f 6e 73 20 74 68 61 74 20 77 69 6e 64 20 69 gons that wind i
3df0: 6e 20 74 68 65 20 77 72 6f 6e 67 20 64 69 72 65 n the wrong dire
3e00: 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 ction..*/.static
3e10: 20 76 6f 69 64 20 67 65 6f 70 6f 6c 79 43 63 77 void geopolyCcw
3e20: 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f Func(. sqlite3_
3e30: 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 context *context
3e40: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 ,. int argc,.
3e50: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a sqlite3_value **
3e60: 61 72 67 76 0a 29 7b 0a 20 20 47 65 6f 50 6f 6c argv.){. GeoPol
3e70: 79 20 2a 70 20 3d 20 67 65 6f 70 6f 6c 79 46 75 y *p = geopolyFu
3e80: 6e 63 50 61 72 61 6d 28 63 6f 6e 74 65 78 74 2c ncParam(context,
3e90: 20 61 72 67 76 5b 30 5d 2c 20 30 29 3b 0a 20 20 argv[0], 0);.
3ea0: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 69 66 28 if( p ){. if(
3eb0: 20 67 65 6f 70 6f 6c 79 41 72 65 61 28 70 29 3c geopolyArea(p)<
3ec0: 30 2e 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 0.0 ){. int
3ed0: 20 69 69 2c 20 6a 6a 3b 0a 20 20 20 20 20 20 66 ii, jj;. f
3ee0: 6f 72 28 69 69 3d 31 2c 20 6a 6a 3d 70 2d 3e 6e or(ii=1, jj=p->n
3ef0: 56 65 72 74 65 78 2d 31 3b 20 69 69 3c 6a 6a 3b Vertex-1; ii<jj;
3f00: 20 69 69 2b 2b 2c 20 6a 6a 2d 2d 29 7b 0a 20 20 ii++, jj--){.
3f10: 20 20 20 20 20 20 47 65 6f 43 6f 6f 72 64 20 74 GeoCoord t
3f20: 20 3d 20 47 65 6f 58 28 70 2c 69 69 29 3b 0a 20 = GeoX(p,ii);.
3f30: 20 20 20 20 20 20 20 47 65 6f 58 28 70 2c 69 69 GeoX(p,ii
3f40: 29 20 3d 20 47 65 6f 58 28 70 2c 6a 6a 29 3b 0a ) = GeoX(p,jj);.
3f50: 20 20 20 20 20 20 20 20 47 65 6f 58 28 70 2c 6a GeoX(p,j
3f60: 6a 29 20 3d 20 74 3b 0a 20 20 20 20 20 20 20 20 j) = t;.
3f70: 74 20 3d 20 47 65 6f 59 28 70 2c 69 69 29 3b 0a t = GeoY(p,ii);.
3f80: 20 20 20 20 20 20 20 20 47 65 6f 59 28 70 2c 69 GeoY(p,i
3f90: 69 29 20 3d 20 47 65 6f 59 28 70 2c 6a 6a 29 3b i) = GeoY(p,jj);
3fa0: 0a 20 20 20 20 20 20 20 20 47 65 6f 59 28 70 2c . GeoY(p,
3fb0: 6a 6a 29 20 3d 20 74 3b 0a 20 20 20 20 20 20 7d jj) = t;. }
3fc0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 . }. sqlit
3fd0: 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 63 e3_result_blob(c
3fe0: 6f 6e 74 65 78 74 2c 20 70 2d 3e 68 64 72 2c 20 ontext, p->hdr,
3ff0: 0a 20 20 20 20 20 20 20 34 2b 38 2a 70 2d 3e 6e . 4+8*p->n
4000: 56 65 72 74 65 78 2c 20 53 51 4c 49 54 45 5f 54 Vertex, SQLITE_T
4010: 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 73 RANSIENT);. s
4020: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a qlite3_free(p);.
4030: 20 20 7d 20 20 20 20 20 20 20 20 20 20 20 20 0a } .
4040: 7d 0a 0a 23 64 65 66 69 6e 65 20 47 45 4f 50 4f }..#define GEOPO
4050: 4c 59 5f 50 49 20 33 2e 31 34 31 35 39 32 36 35 LY_PI 3.14159265
4060: 33 35 38 39 37 39 33 32 33 38 35 0a 0a 2f 2a 20 35897932385../*
4070: 46 61 73 74 20 61 70 70 72 6f 78 69 6d 61 74 69 Fast approximati
4080: 6f 6e 20 66 6f 72 20 73 69 6e 65 28 58 29 20 66 on for sine(X) f
4090: 6f 72 20 58 20 62 65 74 77 65 65 6e 20 2d 30 2e or X between -0.
40a0: 35 2a 70 69 20 61 6e 64 20 32 2a 70 69 0a 2a 2f 5*pi and 2*pi.*/
40b0: 0a 73 74 61 74 69 63 20 64 6f 75 62 6c 65 20 67 .static double g
40c0: 65 6f 70 6f 6c 79 53 69 6e 65 28 64 6f 75 62 6c eopolySine(doubl
40d0: 65 20 72 29 7b 0a 20 20 61 73 73 65 72 74 28 20 e r){. assert(
40e0: 72 3e 3d 2d 30 2e 35 2a 47 45 4f 50 4f 4c 59 5f r>=-0.5*GEOPOLY_
40f0: 50 49 20 26 26 20 72 3c 3d 32 2e 30 2a 47 45 4f PI && r<=2.0*GEO
4100: 50 4f 4c 59 5f 50 49 20 29 3b 0a 20 20 69 66 28 POLY_PI );. if(
4110: 20 72 3e 3d 31 2e 35 2a 47 45 4f 50 4f 4c 59 5f r>=1.5*GEOPOLY_
4120: 50 49 20 29 7b 0a 20 20 20 20 72 20 2d 3d 20 32 PI ){. r -= 2
4130: 2e 30 2a 47 45 4f 50 4f 4c 59 5f 50 49 3b 0a 20 .0*GEOPOLY_PI;.
4140: 20 7d 0a 20 20 69 66 28 20 72 3e 3d 30 2e 35 2a }. if( r>=0.5*
4150: 47 45 4f 50 4f 4c 59 5f 50 49 20 29 7b 0a 20 20 GEOPOLY_PI ){.
4160: 20 20 72 65 74 75 72 6e 20 2d 67 65 6f 70 6f 6c return -geopol
4170: 79 53 69 6e 65 28 72 2d 47 45 4f 50 4f 4c 59 5f ySine(r-GEOPOLY_
4180: 50 49 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 PI);. }else{.
4190: 20 20 64 6f 75 62 6c 65 20 72 32 20 3d 20 72 2a double r2 = r*
41a0: 72 3b 0a 20 20 20 20 64 6f 75 62 6c 65 20 72 33 r;. double r3
41b0: 20 3d 20 72 32 2a 72 3b 0a 20 20 20 20 64 6f 75 = r2*r;. dou
41c0: 62 6c 65 20 72 35 20 3d 20 72 33 2a 72 32 3b 0a ble r5 = r3*r2;.
41d0: 20 20 20 20 72 65 74 75 72 6e 20 30 2e 39 39 39 return 0.999
41e0: 36 39 34 39 2a 72 20 2d 20 30 2e 31 36 35 36 37 6949*r - 0.16567
41f0: 30 30 2a 72 33 20 2b 20 30 2e 30 30 37 35 31 33 00*r3 + 0.007513
4200: 34 2a 72 35 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 4*r5;. }.}../*.
4210: 2a 2a 20 46 75 6e 63 74 69 6f 6e 3a 20 20 20 67 ** Function: g
4220: 65 6f 70 6f 6c 79 5f 72 65 67 75 6c 61 72 28 58 eopoly_regular(X
4230: 2c 59 2c 52 2c 4e 29 0a 2a 2a 0a 2a 2a 20 43 6f ,Y,R,N).**.** Co
4240: 6e 73 74 72 75 63 74 20 61 20 73 69 6d 70 6c 65 nstruct a simple
4250: 2c 20 63 6f 6e 76 65 78 2c 20 72 65 67 75 6c 61 , convex, regula
4260: 72 20 70 6f 6c 79 67 6f 6e 20 63 65 6e 74 65 72 r polygon center
4270: 65 64 20 61 74 20 58 2c 20 59 0a 2a 2a 20 77 69 ed at X, Y.** wi
4280: 74 68 20 63 69 72 63 75 6d 72 61 64 69 75 73 20 th circumradius
4290: 52 20 61 6e 64 20 77 69 74 68 20 4e 20 73 69 64 R and with N sid
42a0: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f es..*/.static vo
42b0: 69 64 20 67 65 6f 70 6f 6c 79 52 65 67 75 6c 61 id geopolyRegula
42c0: 72 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 rFunc(. sqlite3
42d0: 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 _context *contex
42e0: 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 t,. int argc,.
42f0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a sqlite3_value *
4300: 2a 61 72 67 76 0a 29 7b 0a 20 20 64 6f 75 62 6c *argv.){. doubl
4310: 65 20 78 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 e x = sqlite3_va
4320: 6c 75 65 5f 64 6f 75 62 6c 65 28 61 72 67 76 5b lue_double(argv[
4330: 30 5d 29 3b 0a 20 20 64 6f 75 62 6c 65 20 79 20 0]);. double y
4340: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f = sqlite3_value_
4350: 64 6f 75 62 6c 65 28 61 72 67 76 5b 31 5d 29 3b double(argv[1]);
4360: 0a 20 20 64 6f 75 62 6c 65 20 72 20 3d 20 73 71 . double r = sq
4370: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75 62 lite3_value_doub
4380: 6c 65 28 61 72 67 76 5b 32 5d 29 3b 0a 20 20 69 le(argv[2]);. i
4390: 6e 74 20 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76 nt n = sqlite3_v
43a0: 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b 33 5d alue_int(argv[3]
43b0: 29 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 47 65 );. int i;. Ge
43c0: 6f 50 6f 6c 79 20 2a 70 3b 0a 0a 20 20 69 66 28 oPoly *p;.. if(
43d0: 20 6e 3c 33 20 7c 7c 20 72 3c 3d 30 2e 30 20 29 n<3 || r<=0.0 )
43e0: 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 6e return;. if( n
43f0: 3e 31 30 30 30 20 29 20 6e 20 3d 20 31 30 30 30 >1000 ) n = 1000
4400: 3b 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33 5f ;. p = sqlite3_
4410: 6d 61 6c 6c 6f 63 36 34 28 20 73 69 7a 65 6f 66 malloc64( sizeof
4420: 28 2a 70 29 20 2b 20 28 6e 2d 31 29 2a 32 2a 73 (*p) + (n-1)*2*s
4430: 69 7a 65 6f 66 28 47 65 6f 43 6f 6f 72 64 29 20 izeof(GeoCoord)
4440: 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b );. if( p==0 ){
4450: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 . sqlite3_res
4460: 75 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 6d 28 ult_error_nomem(
4470: 63 6f 6e 74 65 78 74 29 3b 0a 20 20 20 20 72 65 context);. re
4480: 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 69 20 3d 20 turn;. }. i =
4490: 31 3b 0a 20 20 70 2d 3e 68 64 72 5b 30 5d 20 3d 1;. p->hdr[0] =
44a0: 20 2a 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 *(unsigned char
44b0: 2a 29 26 69 3b 0a 20 20 70 2d 3e 68 64 72 5b 31 *)&i;. p->hdr[1
44c0: 5d 20 3d 20 30 3b 0a 20 20 70 2d 3e 68 64 72 5b ] = 0;. p->hdr[
44d0: 32 5d 20 3d 20 28 6e 3e 3e 38 29 26 30 78 66 66 2] = (n>>8)&0xff
44e0: 3b 0a 20 20 70 2d 3e 68 64 72 5b 33 5d 20 3d 20 ;. p->hdr[3] =
44f0: 6e 26 30 78 66 66 3b 0a 20 20 66 6f 72 28 69 3d n&0xff;. for(i=
4500: 30 3b 20 69 3c 6e 3b 20 69 2b 2b 29 7b 0a 20 20 0; i<n; i++){.
4510: 20 20 64 6f 75 62 6c 65 20 72 41 6e 67 6c 65 20 double rAngle
4520: 3d 20 32 2e 30 2a 47 45 4f 50 4f 4c 59 5f 50 49 = 2.0*GEOPOLY_PI
4530: 2a 69 2f 6e 3b 0a 20 20 20 20 47 65 6f 58 28 70 *i/n;. GeoX(p
4540: 2c 69 29 20 3d 20 78 20 2d 20 72 2a 67 65 6f 70 ,i) = x - r*geop
4550: 6f 6c 79 53 69 6e 65 28 72 41 6e 67 6c 65 2d 30 olySine(rAngle-0
4560: 2e 35 2a 47 45 4f 50 4f 4c 59 5f 50 49 29 3b 0a .5*GEOPOLY_PI);.
4570: 20 20 20 20 47 65 6f 59 28 70 2c 69 29 20 3d 20 GeoY(p,i) =
4580: 79 20 2b 20 72 2a 67 65 6f 70 6f 6c 79 53 69 6e y + r*geopolySin
4590: 65 28 72 41 6e 67 6c 65 29 3b 0a 20 20 7d 0a 20 e(rAngle);. }.
45a0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f sqlite3_result_
45b0: 62 6c 6f 62 28 63 6f 6e 74 65 78 74 2c 20 70 2d blob(context, p-
45c0: 3e 68 64 72 2c 20 34 2b 38 2a 6e 2c 20 53 51 4c >hdr, 4+8*n, SQL
45d0: 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a ITE_TRANSIENT);.
45e0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 sqlite3_free(p
45f0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 70 );.}../*.** If p
4600: 50 6f 6c 79 20 69 73 20 61 20 70 6f 6c 79 67 6f Poly is a polygo
4610: 6e 2c 20 63 6f 6d 70 75 74 65 20 69 74 73 20 62 n, compute its b
4620: 6f 75 6e 64 69 6e 67 20 62 6f 78 2e 20 54 68 65 ounding box. The
4630: 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 28 31 29 20 n:.**.** (1)
4640: 69 66 20 61 43 6f 6f 72 64 21 3d 30 20 73 74 6f if aCoord!=0 sto
4650: 72 65 20 74 68 65 20 62 6f 75 6e 64 69 6e 67 20 re the bounding
4660: 62 6f 78 20 69 6e 20 61 43 6f 6f 72 64 2c 20 72 box in aCoord, r
4670: 65 74 75 72 6e 69 6e 67 20 4e 55 4c 4c 0a 2a 2a eturning NULL.**
4680: 20 20 20 20 28 32 29 20 6f 74 68 65 72 77 69 73 (2) otherwis
4690: 65 2c 20 63 6f 6d 70 75 74 65 20 61 20 47 65 6f e, compute a Geo
46a0: 50 6f 6c 79 20 66 6f 72 20 74 68 65 20 62 6f 75 Poly for the bou
46b0: 6e 64 69 6e 67 20 62 6f 78 20 61 6e 64 20 72 65 nding box and re
46c0: 74 75 72 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20 turn the.**
46d0: 20 20 20 6e 65 77 20 47 65 6f 50 6f 6c 79 0a 2a new GeoPoly.*
46e0: 2a 0a 2a 2a 20 49 66 20 70 50 6f 6c 79 20 69 73 *.** If pPoly is
46f0: 20 4e 55 4c 4c 20 62 75 74 20 61 43 6f 6f 72 64 NULL but aCoord
4700: 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68 is not NULL, th
4710: 65 6e 20 63 6f 6d 70 75 74 65 20 61 20 6e 65 77 en compute a new
4720: 20 47 65 6f 50 6f 6c 79 20 66 72 6f 6d 0a 2a 2a GeoPoly from.**
4730: 20 74 68 65 20 62 6f 75 6e 64 69 6e 67 20 62 6f the bounding bo
4740: 78 20 69 6e 20 61 43 6f 6f 72 64 20 61 6e 64 20 x in aCoord and
4750: 72 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 return a pointer
4760: 20 74 6f 20 74 68 61 74 20 47 65 6f 50 6f 6c 79 to that GeoPoly
4770: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 47 65 6f 50 ..*/.static GeoP
4780: 6f 6c 79 20 2a 67 65 6f 70 6f 6c 79 42 42 6f 78 oly *geopolyBBox
4790: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 (. sqlite3_cont
47a0: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 20 20 20 ext *context,
47b0: 2f 2a 20 46 6f 72 20 72 65 63 6f 72 64 69 6e 67 /* For recording
47c0: 20 74 68 65 20 65 72 72 6f 72 20 2a 2f 0a 20 20 the error */.
47d0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 sqlite3_value *p
47e0: 50 6f 6c 79 2c 20 20 20 20 20 20 20 2f 2a 20 54 Poly, /* T
47f0: 68 65 20 70 6f 6c 79 67 6f 6e 20 2a 2f 0a 20 20 he polygon */.
4800: 52 74 72 65 65 43 6f 6f 72 64 20 2a 61 43 6f 6f RtreeCoord *aCoo
4810: 72 64 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 52 rd, /* R
4820: 65 73 75 6c 74 73 20 68 65 72 65 20 2a 2f 0a 20 esults here */.
4830: 20 69 6e 74 20 2a 70 52 63 20 20 20 20 20 20 20 int *pRc
4840: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
4850: 45 72 72 6f 72 20 63 6f 64 65 20 68 65 72 65 20 Error code here
4860: 2a 2f 0a 29 7b 0a 20 20 47 65 6f 50 6f 6c 79 20 */.){. GeoPoly
4870: 2a 70 4f 75 74 20 3d 20 30 3b 0a 20 20 47 65 6f *pOut = 0;. Geo
4880: 50 6f 6c 79 20 2a 70 3b 0a 20 20 66 6c 6f 61 74 Poly *p;. float
4890: 20 6d 6e 58 2c 20 6d 78 58 2c 20 6d 6e 59 2c 20 mnX, mxX, mnY,
48a0: 6d 78 59 3b 0a 20 20 69 66 28 20 70 50 6f 6c 79 mxY;. if( pPoly
48b0: 3d 3d 30 20 26 26 20 61 43 6f 6f 72 64 21 3d 30 ==0 && aCoord!=0
48c0: 20 29 7b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20 ){. p = 0;.
48d0: 20 20 20 6d 6e 58 20 3d 20 61 43 6f 6f 72 64 5b mnX = aCoord[
48e0: 30 5d 2e 66 3b 0a 20 20 20 20 6d 78 58 20 3d 20 0].f;. mxX =
48f0: 61 43 6f 6f 72 64 5b 31 5d 2e 66 3b 0a 20 20 20 aCoord[1].f;.
4900: 20 6d 6e 59 20 3d 20 61 43 6f 6f 72 64 5b 32 5d mnY = aCoord[2]
4910: 2e 66 3b 0a 20 20 20 20 6d 78 59 20 3d 20 61 43 .f;. mxY = aC
4920: 6f 6f 72 64 5b 33 5d 2e 66 3b 0a 20 20 20 20 67 oord[3].f;. g
4930: 6f 74 6f 20 67 65 6f 70 6f 6c 79 42 62 6f 78 46 oto geopolyBboxF
4940: 69 6c 6c 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 ill;. }else{.
4950: 20 20 70 20 3d 20 67 65 6f 70 6f 6c 79 46 75 6e p = geopolyFun
4960: 63 50 61 72 61 6d 28 63 6f 6e 74 65 78 74 2c 20 cParam(context,
4970: 70 50 6f 6c 79 2c 20 70 52 63 29 3b 0a 20 20 7d pPoly, pRc);. }
4980: 0a 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 . if( p ){.
4990: 69 6e 74 20 69 69 3b 0a 20 20 20 20 6d 6e 58 20 int ii;. mnX
49a0: 3d 20 6d 78 58 20 3d 20 47 65 6f 58 28 70 2c 30 = mxX = GeoX(p,0
49b0: 29 3b 0a 20 20 20 20 6d 6e 59 20 3d 20 6d 78 59 );. mnY = mxY
49c0: 20 3d 20 47 65 6f 59 28 70 2c 30 29 3b 0a 20 20 = GeoY(p,0);.
49d0: 20 20 66 6f 72 28 69 69 3d 31 3b 20 69 69 3c 70 for(ii=1; ii<p
49e0: 2d 3e 6e 56 65 72 74 65 78 3b 20 69 69 2b 2b 29 ->nVertex; ii++)
49f0: 7b 0a 20 20 20 20 20 20 64 6f 75 62 6c 65 20 72 {. double r
4a00: 20 3d 20 47 65 6f 58 28 70 2c 69 69 29 3b 0a 20 = GeoX(p,ii);.
4a10: 20 20 20 20 20 69 66 28 20 72 3c 6d 6e 58 20 29 if( r<mnX )
4a20: 20 6d 6e 58 20 3d 20 28 66 6c 6f 61 74 29 72 3b mnX = (float)r;
4a30: 0a 20 20 20 20 20 20 65 6c 73 65 20 69 66 28 20 . else if(
4a40: 72 3e 6d 78 58 20 29 20 6d 78 58 20 3d 20 28 66 r>mxX ) mxX = (f
4a50: 6c 6f 61 74 29 72 3b 0a 20 20 20 20 20 20 72 20 loat)r;. r
4a60: 3d 20 47 65 6f 59 28 70 2c 69 69 29 3b 0a 20 20 = GeoY(p,ii);.
4a70: 20 20 20 20 69 66 28 20 72 3c 6d 6e 59 20 29 20 if( r<mnY )
4a80: 6d 6e 59 20 3d 20 28 66 6c 6f 61 74 29 72 3b 0a mnY = (float)r;.
4a90: 20 20 20 20 20 20 65 6c 73 65 20 69 66 28 20 72 else if( r
4aa0: 3e 6d 78 59 20 29 20 6d 78 59 20 3d 20 28 66 6c >mxY ) mxY = (fl
4ab0: 6f 61 74 29 72 3b 0a 20 20 20 20 7d 0a 20 20 20 oat)r;. }.
4ac0: 20 69 66 28 20 70 52 63 20 29 20 2a 70 52 63 20 if( pRc ) *pRc
4ad0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 = SQLITE_OK;.
4ae0: 20 69 66 28 20 61 43 6f 6f 72 64 3d 3d 30 20 29 if( aCoord==0 )
4af0: 7b 0a 20 20 20 20 20 20 67 65 6f 70 6f 6c 79 42 {. geopolyB
4b00: 62 6f 78 46 69 6c 6c 3a 0a 20 20 20 20 20 20 70 boxFill:. p
4b10: 4f 75 74 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 Out = sqlite3_re
4b20: 61 6c 6c 6f 63 28 70 2c 20 47 45 4f 50 4f 4c 59 alloc(p, GEOPOLY
4b30: 5f 53 5a 28 34 29 29 3b 0a 20 20 20 20 20 20 69 _SZ(4));. i
4b40: 66 28 20 70 4f 75 74 3d 3d 30 20 29 7b 0a 20 20 f( pOut==0 ){.
4b50: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 sqlite3_fr
4b60: 65 65 28 70 29 3b 0a 20 20 20 20 20 20 20 20 69 ee(p);. i
4b70: 66 28 20 63 6f 6e 74 65 78 74 20 29 20 73 71 6c f( context ) sql
4b80: 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f ite3_result_erro
4b90: 72 5f 6e 6f 6d 65 6d 28 63 6f 6e 74 65 78 74 29 r_nomem(context)
4ba0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 52 ;. if( pR
4bb0: 63 20 29 20 2a 70 52 63 20 3d 20 53 51 4c 49 54 c ) *pRc = SQLIT
4bc0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20 E_NOMEM;.
4bd0: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 return 0;.
4be0: 20 7d 0a 20 20 20 20 20 20 70 4f 75 74 2d 3e 6e }. pOut->n
4bf0: 56 65 72 74 65 78 20 3d 20 34 3b 0a 20 20 20 20 Vertex = 4;.
4c00: 20 20 69 69 20 3d 20 31 3b 0a 20 20 20 20 20 20 ii = 1;.
4c10: 70 4f 75 74 2d 3e 68 64 72 5b 30 5d 20 3d 20 2a pOut->hdr[0] = *
4c20: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 (unsigned char*)
4c30: 26 69 69 3b 0a 20 20 20 20 20 20 70 4f 75 74 2d ⅈ. pOut-
4c40: 3e 68 64 72 5b 31 5d 20 3d 20 30 3b 0a 20 20 20 >hdr[1] = 0;.
4c50: 20 20 20 70 4f 75 74 2d 3e 68 64 72 5b 32 5d 20 pOut->hdr[2]
4c60: 3d 20 30 3b 0a 20 20 20 20 20 20 70 4f 75 74 2d = 0;. pOut-
4c70: 3e 68 64 72 5b 33 5d 20 3d 20 34 3b 0a 20 20 20 >hdr[3] = 4;.
4c80: 20 20 20 47 65 6f 58 28 70 4f 75 74 2c 30 29 20 GeoX(pOut,0)
4c90: 3d 20 6d 6e 58 3b 0a 20 20 20 20 20 20 47 65 6f = mnX;. Geo
4ca0: 59 28 70 4f 75 74 2c 30 29 20 3d 20 6d 6e 59 3b Y(pOut,0) = mnY;
4cb0: 0a 20 20 20 20 20 20 47 65 6f 58 28 70 4f 75 74 . GeoX(pOut
4cc0: 2c 31 29 20 3d 20 6d 78 58 3b 0a 20 20 20 20 20 ,1) = mxX;.
4cd0: 20 47 65 6f 59 28 70 4f 75 74 2c 31 29 20 3d 20 GeoY(pOut,1) =
4ce0: 6d 6e 59 3b 0a 20 20 20 20 20 20 47 65 6f 58 28 mnY;. GeoX(
4cf0: 70 4f 75 74 2c 32 29 20 3d 20 6d 78 58 3b 0a 20 pOut,2) = mxX;.
4d00: 20 20 20 20 20 47 65 6f 59 28 70 4f 75 74 2c 32 GeoY(pOut,2
4d10: 29 20 3d 20 6d 78 59 3b 0a 20 20 20 20 20 20 47 ) = mxY;. G
4d20: 65 6f 58 28 70 4f 75 74 2c 33 29 20 3d 20 6d 6e eoX(pOut,3) = mn
4d30: 58 3b 0a 20 20 20 20 20 20 47 65 6f 59 28 70 4f X;. GeoY(pO
4d40: 75 74 2c 33 29 20 3d 20 6d 78 59 3b 0a 20 20 20 ut,3) = mxY;.
4d50: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 }else{. sq
4d60: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 lite3_free(p);.
4d70: 20 20 20 20 20 61 43 6f 6f 72 64 5b 30 5d 2e 66 aCoord[0].f
4d80: 20 3d 20 6d 6e 58 3b 0a 20 20 20 20 20 20 61 43 = mnX;. aC
4d90: 6f 6f 72 64 5b 31 5d 2e 66 20 3d 20 6d 78 58 3b oord[1].f = mxX;
4da0: 0a 20 20 20 20 20 20 61 43 6f 6f 72 64 5b 32 5d . aCoord[2]
4db0: 2e 66 20 3d 20 6d 6e 59 3b 0a 20 20 20 20 20 20 .f = mnY;.
4dc0: 61 43 6f 6f 72 64 5b 33 5d 2e 66 20 3d 20 6d 78 aCoord[3].f = mx
4dd0: 59 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 Y;. }. }. r
4de0: 65 74 75 72 6e 20 70 4f 75 74 3b 0a 7d 0a 0a 2f eturn pOut;.}../
4df0: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 *.** Implementat
4e00: 69 6f 6e 20 6f 66 20 74 68 65 20 67 65 6f 70 6f ion of the geopo
4e10: 6c 79 5f 62 62 6f 78 28 58 29 20 53 51 4c 20 66 ly_bbox(X) SQL f
4e20: 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 unction..*/.stat
4e30: 69 63 20 76 6f 69 64 20 67 65 6f 70 6f 6c 79 42 ic void geopolyB
4e40: 42 6f 78 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 BoxFunc(. sqlit
4e50: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 e3_context *cont
4e60: 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c ext,. int argc,
4e70: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 . sqlite3_value
4e80: 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 47 65 6f **argv.){. Geo
4e90: 50 6f 6c 79 20 2a 70 20 3d 20 67 65 6f 70 6f 6c Poly *p = geopol
4ea0: 79 42 42 6f 78 28 63 6f 6e 74 65 78 74 2c 20 61 yBBox(context, a
4eb0: 72 67 76 5b 30 5d 2c 20 30 2c 20 30 29 3b 0a 20 rgv[0], 0, 0);.
4ec0: 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 73 71 if( p ){. sq
4ed0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f lite3_result_blo
4ee0: 62 28 63 6f 6e 74 65 78 74 2c 20 70 2d 3e 68 64 b(context, p->hd
4ef0: 72 2c 20 0a 20 20 20 20 20 20 20 34 2b 38 2a 70 r, . 4+8*p
4f00: 2d 3e 6e 56 65 72 74 65 78 2c 20 53 51 4c 49 54 ->nVertex, SQLIT
4f10: 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 E_TRANSIENT);.
4f20: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 sqlite3_free(p
4f30: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 );. }.}../*.**
4f40: 53 74 61 74 65 20 76 65 63 74 6f 72 20 66 6f 72 State vector for
4f50: 20 74 68 65 20 67 65 6f 70 6f 6c 79 5f 67 72 6f the geopoly_gro
4f60: 75 70 5f 62 62 6f 78 28 29 20 61 67 67 72 65 67 up_bbox() aggreg
4f70: 61 74 65 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f ate function..*/
4f80: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 .typedef struct
4f90: 47 65 6f 42 42 6f 78 20 47 65 6f 42 42 6f 78 3b GeoBBox GeoBBox;
4fa0: 0a 73 74 72 75 63 74 20 47 65 6f 42 42 6f 78 20 .struct GeoBBox
4fb0: 7b 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 0a {. int isInit;.
4fc0: 20 20 52 74 72 65 65 43 6f 6f 72 64 20 61 5b 34 RtreeCoord a[4
4fd0: 5d 3b 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d ];.};.../*.** Im
4fe0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 plementation of
4ff0: 74 68 65 20 67 65 6f 70 6f 6c 79 5f 67 72 6f 75 the geopoly_grou
5000: 70 5f 62 62 6f 78 28 58 29 20 61 67 67 72 65 67 p_bbox(X) aggreg
5010: 61 74 65 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e ate SQL function
5020: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 ..*/.static void
5030: 20 67 65 6f 70 6f 6c 79 42 42 6f 78 53 74 65 70 geopolyBBoxStep
5040: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 (. sqlite3_cont
5050: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 ext *context,.
5060: 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 int argc,. sqli
5070: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 te3_value **argv
5080: 0a 29 7b 0a 20 20 52 74 72 65 65 43 6f 6f 72 64 .){. RtreeCoord
5090: 20 61 5b 34 5d 3b 0a 20 20 69 6e 74 20 72 63 20 a[4];. int rc
50a0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 28 = SQLITE_OK;. (
50b0: 76 6f 69 64 29 67 65 6f 70 6f 6c 79 42 42 6f 78 void)geopolyBBox
50c0: 28 63 6f 6e 74 65 78 74 2c 20 61 72 67 76 5b 30 (context, argv[0
50d0: 5d 2c 20 61 2c 20 26 72 63 29 3b 0a 20 20 69 66 ], a, &rc);. if
50e0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 ( rc==SQLITE_OK
50f0: 29 7b 0a 20 20 20 20 47 65 6f 42 42 6f 78 20 2a ){. GeoBBox *
5100: 70 42 42 6f 78 3b 0a 20 20 20 20 70 42 42 6f 78 pBBox;. pBBox
5110: 20 3d 20 28 47 65 6f 42 42 6f 78 2a 29 73 71 6c = (GeoBBox*)sql
5120: 69 74 65 33 5f 61 67 67 72 65 67 61 74 65 5f 63 ite3_aggregate_c
5130: 6f 6e 74 65 78 74 28 63 6f 6e 74 65 78 74 2c 20 ontext(context,
5140: 73 69 7a 65 6f 66 28 2a 70 42 42 6f 78 29 29 3b sizeof(*pBBox));
5150: 0a 20 20 20 20 69 66 28 20 70 42 42 6f 78 3d 3d . if( pBBox==
5160: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 0 ) return;.
5170: 69 66 28 20 70 42 42 6f 78 2d 3e 69 73 49 6e 69 if( pBBox->isIni
5180: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 42 t==0 ){. pB
5190: 42 6f 78 2d 3e 69 73 49 6e 69 74 20 3d 20 31 3b Box->isInit = 1;
51a0: 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70 42 . memcpy(pB
51b0: 42 6f 78 2d 3e 61 2c 20 61 2c 20 73 69 7a 65 6f Box->a, a, sizeo
51c0: 66 28 52 74 72 65 65 43 6f 6f 72 64 29 2a 34 29 f(RtreeCoord)*4)
51d0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 ;. }else{.
51e0: 20 20 20 69 66 28 20 61 5b 30 5d 2e 66 20 3c 20 if( a[0].f <
51f0: 70 42 42 6f 78 2d 3e 61 5b 30 5d 2e 66 20 29 20 pBBox->a[0].f )
5200: 70 42 42 6f 78 2d 3e 61 5b 30 5d 20 3d 20 61 5b pBBox->a[0] = a[
5210: 30 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 61 5b 0];. if( a[
5220: 31 5d 2e 66 20 3e 20 70 42 42 6f 78 2d 3e 61 5b 1].f > pBBox->a[
5230: 31 5d 2e 66 20 29 20 70 42 42 6f 78 2d 3e 61 5b 1].f ) pBBox->a[
5240: 31 5d 20 3d 20 61 5b 31 5d 3b 0a 20 20 20 20 20 1] = a[1];.
5250: 20 69 66 28 20 61 5b 32 5d 2e 66 20 3c 20 70 42 if( a[2].f < pB
5260: 42 6f 78 2d 3e 61 5b 32 5d 2e 66 20 29 20 70 42 Box->a[2].f ) pB
5270: 42 6f 78 2d 3e 61 5b 32 5d 20 3d 20 61 5b 32 5d Box->a[2] = a[2]
5280: 3b 0a 20 20 20 20 20 20 69 66 28 20 61 5b 33 5d ;. if( a[3]
5290: 2e 66 20 3e 20 70 42 42 6f 78 2d 3e 61 5b 33 5d .f > pBBox->a[3]
52a0: 2e 66 20 29 20 70 42 42 6f 78 2d 3e 61 5b 33 5d .f ) pBBox->a[3]
52b0: 20 3d 20 61 5b 33 5d 3b 0a 20 20 20 20 7d 0a 20 = a[3];. }.
52c0: 20 7d 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 }.}.static void
52d0: 20 67 65 6f 70 6f 6c 79 42 42 6f 78 46 69 6e 61 geopolyBBoxFina
52e0: 6c 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e l(. sqlite3_con
52f0: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 0a 29 7b text *context.){
5300: 0a 20 20 47 65 6f 50 6f 6c 79 20 2a 70 3b 0a 20 . GeoPoly *p;.
5310: 20 47 65 6f 42 42 6f 78 20 2a 70 42 42 6f 78 3b GeoBBox *pBBox;
5320: 0a 20 20 70 42 42 6f 78 20 3d 20 28 47 65 6f 42 . pBBox = (GeoB
5330: 42 6f 78 2a 29 73 71 6c 69 74 65 33 5f 61 67 67 Box*)sqlite3_agg
5340: 72 65 67 61 74 65 5f 63 6f 6e 74 65 78 74 28 63 regate_context(c
5350: 6f 6e 74 65 78 74 2c 20 30 29 3b 0a 20 20 69 66 ontext, 0);. if
5360: 28 20 70 42 42 6f 78 3d 3d 30 20 29 20 72 65 74 ( pBBox==0 ) ret
5370: 75 72 6e 3b 0a 20 20 70 20 3d 20 67 65 6f 70 6f urn;. p = geopo
5380: 6c 79 42 42 6f 78 28 63 6f 6e 74 65 78 74 2c 20 lyBBox(context,
5390: 30 2c 20 70 42 42 6f 78 2d 3e 61 2c 20 30 29 3b 0, pBBox->a, 0);
53a0: 0a 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 . if( p ){.
53b0: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 sqlite3_result_b
53c0: 6c 6f 62 28 63 6f 6e 74 65 78 74 2c 20 70 2d 3e lob(context, p->
53d0: 68 64 72 2c 20 0a 20 20 20 20 20 20 20 34 2b 38 hdr, . 4+8
53e0: 2a 70 2d 3e 6e 56 65 72 74 65 78 2c 20 53 51 4c *p->nVertex, SQL
53f0: 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a ITE_TRANSIENT);.
5400: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 sqlite3_free
5410: 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a (p);. }.}.../*.
5420: 2a 2a 20 44 65 74 65 72 6d 69 6e 65 20 69 66 20 ** Determine if
5430: 70 6f 69 6e 74 20 28 78 30 2c 79 30 29 20 69 73 point (x0,y0) is
5440: 20 62 65 6e 65 61 74 68 20 6c 69 6e 65 20 73 65 beneath line se
5450: 67 6d 65 6e 74 20 28 78 31 2c 79 31 29 2d 3e 28 gment (x1,y1)->(
5460: 78 32 2c 79 32 29 2e 0a 2a 2a 20 52 65 74 75 72 x2,y2)..** Retur
5470: 6e 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 2b 32 20 ns:.**.** +2
5480: 20 78 30 2c 79 30 20 69 73 20 6f 6e 20 74 68 65 x0,y0 is on the
5490: 20 6c 69 6e 65 20 73 65 67 65 6d 65 6e 74 0a 2a line segement.*
54a0: 2a 0a 2a 2a 20 20 20 20 2b 31 20 20 78 30 2c 79 *.** +1 x0,y
54b0: 30 20 69 73 20 62 65 6e 65 61 74 68 20 6c 69 6e 0 is beneath lin
54c0: 65 20 73 65 67 6d 65 6e 74 0a 2a 2a 0a 2a 2a 20 e segment.**.**
54d0: 20 20 20 30 20 20 20 78 30 2c 79 30 20 69 73 20 0 x0,y0 is
54e0: 6e 6f 74 20 6f 6e 20 6f 72 20 62 65 6e 65 61 74 not on or beneat
54f0: 68 20 74 68 65 20 6c 69 6e 65 20 73 65 67 6d 65 h the line segme
5500: 6e 74 20 6f 72 20 74 68 65 20 6c 69 6e 65 20 73 nt or the line s
5510: 65 67 6d 65 6e 74 0a 2a 2a 20 20 20 20 20 20 20 egment.**
5520: 20 69 73 20 76 65 72 74 69 63 61 6c 20 61 6e 64 is vertical and
5530: 20 78 30 2c 79 30 20 69 73 20 6e 6f 74 20 6f 6e x0,y0 is not on
5540: 20 74 68 65 20 6c 69 6e 65 20 73 65 67 6d 65 6e the line segmen
5550: 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c 65 66 74 t.**.** The left
5560: 2d 6d 6f 73 74 20 63 6f 6f 72 64 69 6e 61 74 65 -most coordinate
5570: 20 6d 69 6e 28 78 31 2c 78 32 29 20 69 73 20 6e min(x1,x2) is n
5580: 6f 74 20 63 6f 6e 73 69 64 65 72 65 64 20 74 6f ot considered to
5590: 20 62 65 20 70 61 72 74 20 6f 66 0a 2a 2a 20 74 be part of.** t
55a0: 68 65 20 6c 69 6e 65 20 73 65 67 6d 65 6e 74 20 he line segment
55b0: 66 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 for the purposes
55c0: 20 6f 66 20 74 68 69 73 20 61 6e 61 6c 79 73 69 of this analysi
55d0: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 s..*/.static int
55e0: 20 70 6f 69 6e 74 42 65 6e 65 61 74 68 4c 69 6e pointBeneathLin
55f0: 65 28 0a 20 20 64 6f 75 62 6c 65 20 78 30 2c 20 e(. double x0,
5600: 64 6f 75 62 6c 65 20 79 30 2c 0a 20 20 64 6f 75 double y0,. dou
5610: 62 6c 65 20 78 31 2c 20 64 6f 75 62 6c 65 20 79 ble x1, double y
5620: 31 2c 0a 20 20 64 6f 75 62 6c 65 20 78 32 2c 20 1,. double x2,
5630: 64 6f 75 62 6c 65 20 79 32 0a 29 7b 0a 20 20 64 double y2.){. d
5640: 6f 75 62 6c 65 20 79 3b 0a 20 20 69 66 28 20 78 ouble y;. if( x
5650: 30 3d 3d 78 31 20 26 26 20 79 30 3d 3d 79 31 20 0==x1 && y0==y1
5660: 29 20 72 65 74 75 72 6e 20 32 3b 0a 20 20 69 66 ) return 2;. if
5670: 28 20 78 31 3c 78 32 20 29 7b 0a 20 20 20 20 69 ( x1<x2 ){. i
5680: 66 28 20 78 30 3c 3d 78 31 20 7c 7c 20 78 30 3e f( x0<=x1 || x0>
5690: 78 32 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 x2 ) return 0;.
56a0: 20 7d 65 6c 73 65 20 69 66 28 20 78 31 3e 78 32 }else if( x1>x2
56b0: 20 29 7b 0a 20 20 20 20 69 66 28 20 78 30 3c 3d ){. if( x0<=
56c0: 78 32 20 7c 7c 20 78 30 3e 78 31 20 29 20 72 65 x2 || x0>x1 ) re
56d0: 74 75 72 6e 20 30 3b 0a 20 20 7d 65 6c 73 65 7b turn 0;. }else{
56e0: 0a 20 20 20 20 2f 2a 20 56 65 72 74 69 63 61 6c . /* Vertical
56f0: 20 6c 69 6e 65 20 73 65 67 6d 65 6e 74 20 2a 2f line segment */
5700: 0a 20 20 20 20 69 66 28 20 78 30 21 3d 78 31 20 . if( x0!=x1
5710: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 ) return 0;.
5720: 69 66 28 20 79 30 3c 79 31 20 26 26 20 79 30 3c if( y0<y1 && y0<
5730: 79 32 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 y2 ) return 0;.
5740: 20 20 20 69 66 28 20 79 30 3e 79 31 20 26 26 20 if( y0>y1 &&
5750: 79 30 3e 79 32 20 29 20 72 65 74 75 72 6e 20 30 y0>y2 ) return 0
5760: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 32 3b 0a ;. return 2;.
5770: 20 20 7d 0a 20 20 79 20 3d 20 79 31 20 2b 20 28 }. y = y1 + (
5780: 79 32 2d 79 31 29 2a 28 78 30 2d 78 31 29 2f 28 y2-y1)*(x0-x1)/(
5790: 78 32 2d 78 31 29 3b 0a 20 20 69 66 28 20 79 30 x2-x1);. if( y0
57a0: 3d 3d 79 20 29 20 72 65 74 75 72 6e 20 32 3b 0a ==y ) return 2;.
57b0: 20 20 69 66 28 20 79 30 3c 79 20 29 20 72 65 74 if( y0<y ) ret
57c0: 75 72 6e 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 urn 1;. return
57d0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 51 4c 20 0;.}../*.** SQL
57e0: 66 75 6e 63 74 69 6f 6e 3a 20 20 20 20 67 65 6f function: geo
57f0: 70 6f 6c 79 5f 63 6f 6e 74 61 69 6e 73 5f 70 6f poly_contains_po
5800: 69 6e 74 28 50 2c 58 2c 59 29 0a 2a 2a 0a 2a 2a int(P,X,Y).**.**
5810: 20 52 65 74 75 72 6e 20 2b 32 20 69 66 20 70 6f Return +2 if po
5820: 69 6e 74 20 58 2c 59 20 69 73 20 77 69 74 68 69 int X,Y is withi
5830: 6e 20 70 6f 6c 79 67 6f 6e 20 50 2e 0a 2a 2a 20 n polygon P..**
5840: 52 65 74 75 72 6e 20 2b 31 20 69 66 20 70 6f 69 Return +1 if poi
5850: 6e 74 20 58 2c 59 20 69 73 20 6f 6e 20 74 68 65 nt X,Y is on the
5860: 20 70 6f 6c 79 67 6f 6e 20 62 6f 75 6e 64 61 72 polygon boundar
5870: 79 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 30 20 69 y..** Return 0 i
5880: 66 20 70 6f 69 6e 74 20 58 2c 59 20 69 73 20 6f f point X,Y is o
5890: 75 74 73 69 64 65 20 74 68 65 20 70 6f 6c 79 67 utside the polyg
58a0: 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 on.*/.static voi
58b0: 64 20 67 65 6f 70 6f 6c 79 43 6f 6e 74 61 69 6e d geopolyContain
58c0: 73 50 6f 69 6e 74 46 75 6e 63 28 0a 20 20 73 71 sPointFunc(. sq
58d0: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 lite3_context *c
58e0: 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 ontext,. int ar
58f0: 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 gc,. sqlite3_va
5900: 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 lue **argv.){.
5910: 47 65 6f 50 6f 6c 79 20 2a 70 31 20 3d 20 67 65 GeoPoly *p1 = ge
5920: 6f 70 6f 6c 79 46 75 6e 63 50 61 72 61 6d 28 63 opolyFuncParam(c
5930: 6f 6e 74 65 78 74 2c 20 61 72 67 76 5b 30 5d 2c ontext, argv[0],
5940: 20 30 29 3b 0a 20 20 64 6f 75 62 6c 65 20 78 30 0);. double x0
5950: 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 = sqlite3_value
5960: 5f 64 6f 75 62 6c 65 28 61 72 67 76 5b 31 5d 29 _double(argv[1])
5970: 3b 0a 20 20 64 6f 75 62 6c 65 20 79 30 20 3d 20 ;. double y0 =
5980: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f sqlite3_value_do
5990: 75 62 6c 65 28 61 72 67 76 5b 32 5d 29 3b 0a 20 uble(argv[2]);.
59a0: 20 69 6e 74 20 76 20 3d 20 30 3b 0a 20 20 69 6e int v = 0;. in
59b0: 74 20 63 6e 74 20 3d 20 30 3b 0a 20 20 69 6e 74 t cnt = 0;. int
59c0: 20 69 69 3b 0a 20 20 69 66 28 20 70 31 3d 3d 30 ii;. if( p1==0
59d0: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 66 6f 72 ) return;. for
59e0: 28 69 69 3d 30 3b 20 69 69 3c 70 31 2d 3e 6e 56 (ii=0; ii<p1->nV
59f0: 65 72 74 65 78 2d 31 3b 20 69 69 2b 2b 29 7b 0a ertex-1; ii++){.
5a00: 20 20 20 20 76 20 3d 20 70 6f 69 6e 74 42 65 6e v = pointBen
5a10: 65 61 74 68 4c 69 6e 65 28 78 30 2c 79 30 2c 47 eathLine(x0,y0,G
5a20: 65 6f 58 28 70 31 2c 69 69 29 2c 20 47 65 6f 59 eoX(p1,ii), GeoY
5a30: 28 70 31 2c 69 69 29 2c 0a 20 20 20 20 20 20 20 (p1,ii),.
5a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
5a50: 20 20 20 20 20 20 20 20 47 65 6f 58 28 70 31 2c GeoX(p1,
5a60: 69 69 2b 31 29 2c 47 65 6f 59 28 70 31 2c 69 69 ii+1),GeoY(p1,ii
5a70: 2b 31 29 29 3b 0a 20 20 20 20 69 66 28 20 76 3d +1));. if( v=
5a80: 3d 32 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 =2 ) break;.
5a90: 63 6e 74 20 2b 3d 20 76 3b 0a 20 20 7d 0a 20 20 cnt += v;. }.
5aa0: 69 66 28 20 76 21 3d 32 20 29 7b 0a 20 20 20 20 if( v!=2 ){.
5ab0: 76 20 3d 20 70 6f 69 6e 74 42 65 6e 65 61 74 68 v = pointBeneath
5ac0: 4c 69 6e 65 28 78 30 2c 79 30 2c 47 65 6f 58 28 Line(x0,y0,GeoX(
5ad0: 70 31 2c 69 69 29 2c 20 47 65 6f 59 28 70 31 2c p1,ii), GeoY(p1,
5ae0: 69 69 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 ii),.
5af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
5b00: 20 20 20 20 47 65 6f 58 28 70 31 2c 30 29 2c 20 GeoX(p1,0),
5b10: 20 47 65 6f 59 28 70 31 2c 30 29 29 3b 0a 20 20 GeoY(p1,0));.
5b20: 7d 0a 20 20 69 66 28 20 76 3d 3d 32 20 29 7b 0a }. if( v==2 ){.
5b30: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 sqlite3_resu
5b40: 6c 74 5f 69 6e 74 28 63 6f 6e 74 65 78 74 2c 20 lt_int(context,
5b50: 31 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 1);. }else if(
5b60: 28 28 76 2b 63 6e 74 29 26 31 29 3d 3d 30 20 29 ((v+cnt)&1)==0 )
5b70: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 {. sqlite3_re
5b80: 73 75 6c 74 5f 69 6e 74 28 63 6f 6e 74 65 78 74 sult_int(context
5b90: 2c 20 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 , 0);. }else{.
5ba0: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c sqlite3_resul
5bb0: 74 5f 69 6e 74 28 63 6f 6e 74 65 78 74 2c 20 32 t_int(context, 2
5bc0: 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 );. }. sqlite3
5bd0: 5f 66 72 65 65 28 70 31 29 3b 0a 7d 0a 0a 2f 2a _free(p1);.}../*
5be0: 20 46 6f 72 77 61 72 64 20 64 65 63 6c 61 72 61 Forward declara
5bf0: 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 tion */.static i
5c00: 6e 74 20 67 65 6f 70 6f 6c 79 4f 76 65 72 6c 61 nt geopolyOverla
5c10: 70 28 47 65 6f 50 6f 6c 79 20 2a 70 31 2c 20 47 p(GeoPoly *p1, G
5c20: 65 6f 50 6f 6c 79 20 2a 70 32 29 3b 0a 0a 2f 2a eoPoly *p2);../*
5c30: 0a 2a 2a 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e .** SQL function
5c40: 3a 20 20 20 20 67 65 6f 70 6f 6c 79 5f 77 69 74 : geopoly_wit
5c50: 68 69 6e 28 50 31 2c 50 32 29 0a 2a 2a 0a 2a 2a hin(P1,P2).**.**
5c60: 20 52 65 74 75 72 6e 20 2b 32 20 69 66 20 50 31 Return +2 if P1
5c70: 20 61 6e 64 20 50 32 20 61 72 65 20 74 68 65 20 and P2 are the
5c80: 73 61 6d 65 20 70 6f 6c 79 67 6f 6e 0a 2a 2a 20 same polygon.**
5c90: 52 65 74 75 72 6e 20 2b 31 20 69 66 20 50 32 20 Return +1 if P2
5ca0: 69 73 20 63 6f 6e 74 61 69 6e 65 64 20 77 69 74 is contained wit
5cb0: 68 69 6e 20 50 31 0a 2a 2a 20 52 65 74 75 72 6e hin P1.** Return
5cc0: 20 30 20 69 66 20 61 6e 79 20 70 61 72 74 20 6f 0 if any part o
5cd0: 66 20 50 32 20 69 73 20 6f 6e 20 74 68 65 20 6f f P2 is on the o
5ce0: 75 74 73 69 64 65 20 6f 66 20 50 31 0a 2a 2a 0a utside of P1.**.
5cf0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 67 */.static void g
5d00: 65 6f 70 6f 6c 79 57 69 74 68 69 6e 46 75 6e 63 eopolyWithinFunc
5d10: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 (. sqlite3_cont
5d20: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 ext *context,.
5d30: 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 int argc,. sqli
5d40: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 te3_value **argv
5d50: 0a 29 7b 0a 20 20 47 65 6f 50 6f 6c 79 20 2a 70 .){. GeoPoly *p
5d60: 31 20 3d 20 67 65 6f 70 6f 6c 79 46 75 6e 63 50 1 = geopolyFuncP
5d70: 61 72 61 6d 28 63 6f 6e 74 65 78 74 2c 20 61 72 aram(context, ar
5d80: 67 76 5b 30 5d 2c 20 30 29 3b 0a 20 20 47 65 6f gv[0], 0);. Geo
5d90: 50 6f 6c 79 20 2a 70 32 20 3d 20 67 65 6f 70 6f Poly *p2 = geopo
5da0: 6c 79 46 75 6e 63 50 61 72 61 6d 28 63 6f 6e 74 lyFuncParam(cont
5db0: 65 78 74 2c 20 61 72 67 76 5b 31 5d 2c 20 30 29 ext, argv[1], 0)
5dc0: 3b 0a 20 20 69 66 28 20 70 31 20 26 26 20 70 32 ;. if( p1 && p2
5dd0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 78 20 3d 20 ){. int x =
5de0: 67 65 6f 70 6f 6c 79 4f 76 65 72 6c 61 70 28 70 geopolyOverlap(p
5df0: 31 2c 20 70 32 29 3b 0a 20 20 20 20 69 66 28 20 1, p2);. if(
5e00: 78 3c 30 20 29 7b 0a 20 20 20 20 20 20 73 71 6c x<0 ){. sql
5e10: 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f ite3_result_erro
5e20: 72 5f 6e 6f 6d 65 6d 28 63 6f 6e 74 65 78 74 29 r_nomem(context)
5e30: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 ;. }else{.
5e40: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c sqlite3_resul
5e50: 74 5f 69 6e 74 28 63 6f 6e 74 65 78 74 2c 20 78 t_int(context, x
5e60: 3d 3d 32 20 3f 20 31 20 3a 20 78 3d 3d 34 20 3f ==2 ? 1 : x==4 ?
5e70: 20 32 20 3a 20 30 29 3b 0a 20 20 20 20 7d 0a 20 2 : 0);. }.
5e80: 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 }. sqlite3_fre
5e90: 65 28 70 31 29 3b 0a 20 20 73 71 6c 69 74 65 33 e(p1);. sqlite3
5ea0: 5f 66 72 65 65 28 70 32 29 3b 0a 7d 0a 0a 2f 2a _free(p2);.}../*
5eb0: 20 4f 62 6a 65 63 74 73 20 75 73 65 64 20 62 79 Objects used by
5ec0: 20 74 68 65 20 6f 76 65 72 6c 61 70 20 61 6c 67 the overlap alg
5ed0: 6f 72 69 68 6d 2e 20 2a 2f 0a 74 79 70 65 64 65 orihm. */.typede
5ee0: 66 20 73 74 72 75 63 74 20 47 65 6f 45 76 65 6e f struct GeoEven
5ef0: 74 20 47 65 6f 45 76 65 6e 74 3b 0a 74 79 70 65 t GeoEvent;.type
5f00: 64 65 66 20 73 74 72 75 63 74 20 47 65 6f 53 65 def struct GeoSe
5f10: 67 6d 65 6e 74 20 47 65 6f 53 65 67 6d 65 6e 74 gment GeoSegment
5f20: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 ;.typedef struct
5f30: 20 47 65 6f 4f 76 65 72 6c 61 70 20 47 65 6f 4f GeoOverlap GeoO
5f40: 76 65 72 6c 61 70 3b 0a 73 74 72 75 63 74 20 47 verlap;.struct G
5f50: 65 6f 45 76 65 6e 74 20 7b 0a 20 20 64 6f 75 62 eoEvent {. doub
5f60: 6c 65 20 78 3b 20 20 20 20 20 20 20 20 20 20 20 le x;
5f70: 20 20 20 2f 2a 20 58 20 63 6f 6f 72 64 69 6e 61 /* X coordina
5f80: 74 65 20 61 74 20 77 68 69 63 68 20 65 76 65 6e te at which even
5f90: 74 20 6f 63 63 75 72 73 20 2a 2f 0a 20 20 69 6e t occurs */. in
5fa0: 74 20 65 54 79 70 65 3b 20 20 20 20 20 20 20 20 t eType;
5fb0: 20 20 20 20 20 2f 2a 20 30 20 66 6f 72 20 41 44 /* 0 for AD
5fc0: 44 2c 20 31 20 66 6f 72 20 52 45 4d 4f 56 45 20 D, 1 for REMOVE
5fd0: 2a 2f 0a 20 20 47 65 6f 53 65 67 6d 65 6e 74 20 */. GeoSegment
5fe0: 2a 70 53 65 67 3b 20 20 20 20 20 20 2f 2a 20 54 *pSeg; /* T
5ff0: 68 65 20 73 65 67 6d 65 6e 74 20 74 6f 20 62 65 he segment to be
6000: 20 61 64 64 65 64 20 6f 72 20 72 65 6d 6f 76 65 added or remove
6010: 64 20 2a 2f 0a 20 20 47 65 6f 45 76 65 6e 74 20 d */. GeoEvent
6020: 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 2f 2a *pNext; /*
6030: 20 4e 65 78 74 20 65 76 65 6e 74 20 69 6e 20 74 Next event in t
6040: 68 65 20 73 6f 72 74 65 64 20 6c 69 73 74 20 2a he sorted list *
6050: 2f 0a 7d 3b 0a 73 74 72 75 63 74 20 47 65 6f 53 /.};.struct GeoS
6060: 65 67 6d 65 6e 74 20 7b 0a 20 20 64 6f 75 62 6c egment {. doubl
6070: 65 20 43 2c 20 42 3b 20 20 20 20 20 20 20 20 20 e C, B;
6080: 20 20 2f 2a 20 79 20 3d 20 43 2a 78 20 2b 20 42 /* y = C*x + B
6090: 20 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 79 3b 20 */. double y;
60a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
60b0: 43 75 72 72 65 6e 74 20 79 20 76 61 6c 75 65 20 Current y value
60c0: 2a 2f 0a 20 20 66 6c 6f 61 74 20 79 30 3b 20 20 */. float y0;
60d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 /* I
60e0: 6e 69 74 69 61 6c 20 79 20 76 61 6c 75 65 20 2a nitial y value *
60f0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 /. unsigned cha
6100: 72 20 73 69 64 65 3b 20 20 20 20 2f 2a 20 31 20 r side; /* 1
6110: 66 6f 72 20 70 31 2c 20 32 20 66 6f 72 20 70 32 for p1, 2 for p2
6120: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 */. unsigned i
6130: 6e 74 20 69 64 78 3b 20 20 20 20 20 20 2f 2a 20 nt idx; /*
6140: 57 68 69 63 68 20 73 65 67 6d 65 6e 74 20 77 69 Which segment wi
6150: 74 68 69 6e 20 74 68 65 20 73 69 64 65 20 2a 2f thin the side */
6160: 0a 20 20 47 65 6f 53 65 67 6d 65 6e 74 20 2a 70 . GeoSegment *p
6170: 4e 65 78 74 3b 20 20 20 20 20 2f 2a 20 4e 65 78 Next; /* Nex
6180: 74 20 73 65 67 6d 65 6e 74 20 69 6e 20 61 20 6c t segment in a l
6190: 69 73 74 20 73 6f 72 74 65 64 20 62 79 20 79 20 ist sorted by y
61a0: 2a 2f 0a 7d 3b 0a 73 74 72 75 63 74 20 47 65 6f */.};.struct Geo
61b0: 4f 76 65 72 6c 61 70 20 7b 0a 20 20 47 65 6f 45 Overlap {. GeoE
61c0: 76 65 6e 74 20 2a 61 45 76 65 6e 74 3b 20 20 20 vent *aEvent;
61d0: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 /* Array
61e0: 6f 66 20 61 6c 6c 20 65 76 65 6e 74 73 20 2a 2f of all events */
61f0: 0a 20 20 47 65 6f 53 65 67 6d 65 6e 74 20 2a 61 . GeoSegment *a
6200: 53 65 67 6d 65 6e 74 3b 20 20 20 20 20 20 2f 2a Segment; /*
6210: 20 41 72 72 61 79 20 6f 66 20 61 6c 6c 20 73 65 Array of all se
6220: 67 6d 65 6e 74 73 20 2a 2f 0a 20 20 69 6e 74 20 gments */. int
6230: 6e 45 76 65 6e 74 3b 20 20 20 20 20 20 20 20 20 nEvent;
6240: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 /* Number
6250: 20 6f 66 20 65 76 65 6e 74 73 20 2a 2f 0a 20 20 of events */.
6260: 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 int nSegment;
6270: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 /* Nu
6280: 6d 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 mber of segments
6290: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 64 */.};../*.** Ad
62a0: 64 20 61 20 73 69 6e 67 6c 65 20 73 65 67 6d 65 d a single segme
62b0: 6e 74 20 61 6e 64 20 69 74 73 20 61 73 73 6f 63 nt and its assoc
62c0: 69 61 74 65 64 20 65 76 65 6e 74 73 2e 0a 2a 2f iated events..*/
62d0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 67 65 6f .static void geo
62e0: 70 6f 6c 79 41 64 64 4f 6e 65 53 65 67 6d 65 6e polyAddOneSegmen
62f0: 74 28 0a 20 20 47 65 6f 4f 76 65 72 6c 61 70 20 t(. GeoOverlap
6300: 2a 70 2c 0a 20 20 47 65 6f 43 6f 6f 72 64 20 78 *p,. GeoCoord x
6310: 30 2c 0a 20 20 47 65 6f 43 6f 6f 72 64 20 79 30 0,. GeoCoord y0
6320: 2c 0a 20 20 47 65 6f 43 6f 6f 72 64 20 78 31 2c ,. GeoCoord x1,
6330: 0a 20 20 47 65 6f 43 6f 6f 72 64 20 79 31 2c 0a . GeoCoord y1,.
6340: 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 unsigned char
6350: 73 69 64 65 2c 0a 20 20 75 6e 73 69 67 6e 65 64 side,. unsigned
6360: 20 69 6e 74 20 69 64 78 0a 29 7b 0a 20 20 47 65 int idx.){. Ge
6370: 6f 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 3b 0a oSegment *pSeg;.
6380: 20 20 47 65 6f 45 76 65 6e 74 20 2a 70 45 76 65 GeoEvent *pEve
6390: 6e 74 3b 0a 20 20 69 66 28 20 78 30 3d 3d 78 31 nt;. if( x0==x1
63a0: 20 29 20 72 65 74 75 72 6e 3b 20 20 2f 2a 20 49 ) return; /* I
63b0: 67 6e 6f 72 65 20 76 65 72 74 69 63 61 6c 20 73 gnore vertical s
63c0: 65 67 6d 65 6e 74 73 20 2a 2f 0a 20 20 69 66 28 egments */. if(
63d0: 20 78 30 3e 78 31 20 29 7b 0a 20 20 20 20 47 65 x0>x1 ){. Ge
63e0: 6f 43 6f 6f 72 64 20 74 20 3d 20 78 30 3b 0a 20 oCoord t = x0;.
63f0: 20 20 20 78 30 20 3d 20 78 31 3b 0a 20 20 20 20 x0 = x1;.
6400: 78 31 20 3d 20 74 3b 0a 20 20 20 20 74 20 3d 20 x1 = t;. t =
6410: 79 30 3b 0a 20 20 20 20 79 30 20 3d 20 79 31 3b y0;. y0 = y1;
6420: 0a 20 20 20 20 79 31 20 3d 20 74 3b 0a 20 20 7d . y1 = t;. }
6430: 0a 20 20 70 53 65 67 20 3d 20 70 2d 3e 61 53 65 . pSeg = p->aSe
6440: 67 6d 65 6e 74 20 2b 20 70 2d 3e 6e 53 65 67 6d gment + p->nSegm
6450: 65 6e 74 3b 0a 20 20 70 2d 3e 6e 53 65 67 6d 65 ent;. p->nSegme
6460: 6e 74 2b 2b 3b 0a 20 20 70 53 65 67 2d 3e 43 20 nt++;. pSeg->C
6470: 3d 20 28 79 31 2d 79 30 29 2f 28 78 31 2d 78 30 = (y1-y0)/(x1-x0
6480: 29 3b 0a 20 20 70 53 65 67 2d 3e 42 20 3d 20 79 );. pSeg->B = y
6490: 31 20 2d 20 78 31 2a 70 53 65 67 2d 3e 43 3b 0a 1 - x1*pSeg->C;.
64a0: 20 20 70 53 65 67 2d 3e 79 30 20 3d 20 79 30 3b pSeg->y0 = y0;
64b0: 0a 20 20 70 53 65 67 2d 3e 73 69 64 65 20 3d 20 . pSeg->side =
64c0: 73 69 64 65 3b 0a 20 20 70 53 65 67 2d 3e 69 64 side;. pSeg->id
64d0: 78 20 3d 20 69 64 78 3b 0a 20 20 70 45 76 65 6e x = idx;. pEven
64e0: 74 20 3d 20 70 2d 3e 61 45 76 65 6e 74 20 2b 20 t = p->aEvent +
64f0: 70 2d 3e 6e 45 76 65 6e 74 3b 0a 20 20 70 2d 3e p->nEvent;. p->
6500: 6e 45 76 65 6e 74 2b 2b 3b 0a 20 20 70 45 76 65 nEvent++;. pEve
6510: 6e 74 2d 3e 78 20 3d 20 78 30 3b 0a 20 20 70 45 nt->x = x0;. pE
6520: 76 65 6e 74 2d 3e 65 54 79 70 65 20 3d 20 30 3b vent->eType = 0;
6530: 0a 20 20 70 45 76 65 6e 74 2d 3e 70 53 65 67 20 . pEvent->pSeg
6540: 3d 20 70 53 65 67 3b 0a 20 20 70 45 76 65 6e 74 = pSeg;. pEvent
6550: 20 3d 20 70 2d 3e 61 45 76 65 6e 74 20 2b 20 70 = p->aEvent + p
6560: 2d 3e 6e 45 76 65 6e 74 3b 0a 20 20 70 2d 3e 6e ->nEvent;. p->n
6570: 45 76 65 6e 74 2b 2b 3b 0a 20 20 70 45 76 65 6e Event++;. pEven
6580: 74 2d 3e 78 20 3d 20 78 31 3b 0a 20 20 70 45 76 t->x = x1;. pEv
6590: 65 6e 74 2d 3e 65 54 79 70 65 20 3d 20 31 3b 0a ent->eType = 1;.
65a0: 20 20 70 45 76 65 6e 74 2d 3e 70 53 65 67 20 3d pEvent->pSeg =
65b0: 20 70 53 65 67 3b 0a 7d 0a 20 20 0a 0a 0a 2f 2a pSeg;.}. .../*
65c0: 0a 2a 2a 20 49 6e 73 65 72 74 20 61 6c 6c 20 73 .** Insert all s
65d0: 65 67 6d 65 6e 74 73 20 61 6e 64 20 65 76 65 6e egments and even
65e0: 74 73 20 66 6f 72 20 70 6f 6c 79 67 6f 6e 20 70 ts for polygon p
65f0: 50 6f 6c 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 Poly..*/.static
6600: 76 6f 69 64 20 67 65 6f 70 6f 6c 79 41 64 64 53 void geopolyAddS
6610: 65 67 6d 65 6e 74 73 28 0a 20 20 47 65 6f 4f 76 egments(. GeoOv
6620: 65 72 6c 61 70 20 2a 70 2c 20 20 20 20 20 20 20 erlap *p,
6630: 20 20 20 2f 2a 20 41 64 64 20 73 65 67 6d 65 6e /* Add segmen
6640: 74 73 20 74 6f 20 74 68 69 73 20 4f 76 65 72 6c ts to this Overl
6650: 61 70 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 47 ap object */. G
6660: 65 6f 50 6f 6c 79 20 2a 70 50 6f 6c 79 2c 20 20 eoPoly *pPoly,
6670: 20 20 20 20 20 20 20 2f 2a 20 54 61 6b 65 20 61 /* Take a
6680: 6c 6c 20 73 65 67 6d 65 6e 74 73 20 66 72 6f 6d ll segments from
6690: 20 74 68 69 73 20 70 6f 6c 79 67 6f 6e 20 2a 2f this polygon */
66a0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 . unsigned char
66b0: 20 73 69 64 65 20 20 20 20 20 20 2f 2a 20 54 68 side /* Th
66c0: 65 20 73 69 64 65 20 6f 66 20 70 50 6f 6c 79 20 e side of pPoly
66d0: 2a 2f 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 */.){. unsigned
66e0: 20 69 6e 74 20 69 3b 0a 20 20 47 65 6f 43 6f 6f int i;. GeoCoo
66f0: 72 64 20 2a 78 3b 0a 20 20 66 6f 72 28 69 3d 30 rd *x;. for(i=0
6700: 3b 20 69 3c 28 75 6e 73 69 67 6e 65 64 29 70 50 ; i<(unsigned)pP
6710: 6f 6c 79 2d 3e 6e 56 65 72 74 65 78 2d 31 3b 20 oly->nVertex-1;
6720: 69 2b 2b 29 7b 0a 20 20 20 20 78 20 3d 20 26 47 i++){. x = &G
6730: 65 6f 58 28 70 50 6f 6c 79 2c 69 29 3b 0a 20 20 eoX(pPoly,i);.
6740: 20 20 67 65 6f 70 6f 6c 79 41 64 64 4f 6e 65 53 geopolyAddOneS
6750: 65 67 6d 65 6e 74 28 70 2c 20 78 5b 30 5d 2c 20 egment(p, x[0],
6760: 78 5b 31 5d 2c 20 78 5b 32 5d 2c 20 78 5b 33 5d x[1], x[2], x[3]
6770: 2c 20 73 69 64 65 2c 20 69 29 3b 0a 20 20 7d 0a , side, i);. }.
6780: 20 20 78 20 3d 20 26 47 65 6f 58 28 70 50 6f 6c x = &GeoX(pPol
6790: 79 2c 69 29 3b 0a 20 20 67 65 6f 70 6f 6c 79 41 y,i);. geopolyA
67a0: 64 64 4f 6e 65 53 65 67 6d 65 6e 74 28 70 2c 20 ddOneSegment(p,
67b0: 78 5b 30 5d 2c 20 78 5b 31 5d 2c 20 70 50 6f 6c x[0], x[1], pPol
67c0: 79 2d 3e 61 5b 30 5d 2c 20 70 50 6f 6c 79 2d 3e y->a[0], pPoly->
67d0: 61 5b 31 5d 2c 20 73 69 64 65 2c 20 69 29 3b 0a a[1], side, i);.
67e0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 }../*.** Merge t
67f0: 77 6f 20 6c 69 73 74 73 20 6f 66 20 73 6f 72 74 wo lists of sort
6800: 65 64 20 65 76 65 6e 74 73 20 62 79 20 58 20 63 ed events by X c
6810: 6f 6f 72 64 69 6e 61 74 65 0a 2a 2f 0a 73 74 61 oordinate.*/.sta
6820: 74 69 63 20 47 65 6f 45 76 65 6e 74 20 2a 67 65 tic GeoEvent *ge
6830: 6f 70 6f 6c 79 45 76 65 6e 74 4d 65 72 67 65 28 opolyEventMerge(
6840: 47 65 6f 45 76 65 6e 74 20 2a 70 4c 65 66 74 2c GeoEvent *pLeft,
6850: 20 47 65 6f 45 76 65 6e 74 20 2a 70 52 69 67 68 GeoEvent *pRigh
6860: 74 29 7b 0a 20 20 47 65 6f 45 76 65 6e 74 20 68 t){. GeoEvent h
6870: 65 61 64 2c 20 2a 70 4c 61 73 74 3b 0a 20 20 68 ead, *pLast;. h
6880: 65 61 64 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 ead.pNext = 0;.
6890: 20 70 4c 61 73 74 20 3d 20 26 68 65 61 64 3b 0a pLast = &head;.
68a0: 20 20 77 68 69 6c 65 28 20 70 52 69 67 68 74 20 while( pRight
68b0: 26 26 20 70 4c 65 66 74 20 29 7b 0a 20 20 20 20 && pLeft ){.
68c0: 69 66 28 20 70 52 69 67 68 74 2d 3e 78 20 3c 3d if( pRight->x <=
68d0: 20 70 4c 65 66 74 2d 3e 78 20 29 7b 0a 20 20 20 pLeft->x ){.
68e0: 20 20 20 70 4c 61 73 74 2d 3e 70 4e 65 78 74 20 pLast->pNext
68f0: 3d 20 70 52 69 67 68 74 3b 0a 20 20 20 20 20 20 = pRight;.
6900: 70 4c 61 73 74 20 3d 20 70 52 69 67 68 74 3b 0a pLast = pRight;.
6910: 20 20 20 20 20 20 70 52 69 67 68 74 20 3d 20 70 pRight = p
6920: 52 69 67 68 74 2d 3e 70 4e 65 78 74 3b 0a 20 20 Right->pNext;.
6930: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 }else{. p
6940: 4c 61 73 74 2d 3e 70 4e 65 78 74 20 3d 20 70 4c Last->pNext = pL
6950: 65 66 74 3b 0a 20 20 20 20 20 20 70 4c 61 73 74 eft;. pLast
6960: 20 3d 20 70 4c 65 66 74 3b 0a 20 20 20 20 20 20 = pLeft;.
6970: 70 4c 65 66 74 20 3d 20 70 4c 65 66 74 2d 3e 70 pLeft = pLeft->p
6980: 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a Next;. }. }.
6990: 20 20 70 4c 61 73 74 2d 3e 70 4e 65 78 74 20 3d pLast->pNext =
69a0: 20 70 52 69 67 68 74 20 3f 20 70 52 69 67 68 74 pRight ? pRight
69b0: 20 3a 20 70 4c 65 66 74 3b 0a 20 20 72 65 74 75 : pLeft;. retu
69c0: 72 6e 20 68 65 61 64 2e 70 4e 65 78 74 3b 20 20 rn head.pNext;
69d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 61 .}../*.** Sort a
69e0: 6e 20 61 72 72 61 79 20 6f 66 20 6e 45 76 65 6e n array of nEven
69f0: 74 20 65 76 65 6e 74 20 6f 62 6a 65 63 74 73 20 t event objects
6a00: 69 6e 74 6f 20 61 20 6c 69 73 74 2e 0a 2a 2f 0a into a list..*/.
6a10: 73 74 61 74 69 63 20 47 65 6f 45 76 65 6e 74 20 static GeoEvent
6a20: 2a 67 65 6f 70 6f 6c 79 53 6f 72 74 45 76 65 6e *geopolySortEven
6a30: 74 73 42 79 58 28 47 65 6f 45 76 65 6e 74 20 2a tsByX(GeoEvent *
6a40: 61 45 76 65 6e 74 2c 20 69 6e 74 20 6e 45 76 65 aEvent, int nEve
6a50: 6e 74 29 7b 0a 20 20 69 6e 74 20 6d 78 20 3d 20 nt){. int mx =
6a60: 30 3b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 0;. int i, j;.
6a70: 20 47 65 6f 45 76 65 6e 74 20 2a 70 3b 0a 20 20 GeoEvent *p;.
6a80: 47 65 6f 45 76 65 6e 74 20 2a 61 5b 35 30 5d 3b GeoEvent *a[50];
6a90: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 45 . for(i=0; i<nE
6aa0: 76 65 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 vent; i++){.
6ab0: 70 20 3d 20 26 61 45 76 65 6e 74 5b 69 5d 3b 0a p = &aEvent[i];.
6ac0: 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 30 p->pNext = 0
6ad0: 3b 0a 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a ;. for(j=0; j
6ae0: 3c 6d 78 20 26 26 20 61 5b 6a 5d 3b 20 6a 2b 2b <mx && a[j]; j++
6af0: 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 67 65 6f ){. p = geo
6b00: 70 6f 6c 79 45 76 65 6e 74 4d 65 72 67 65 28 61 polyEventMerge(a
6b10: 5b 6a 5d 2c 20 70 29 3b 0a 20 20 20 20 20 20 61 [j], p);. a
6b20: 5b 6a 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 [j] = 0;. }.
6b30: 20 20 20 61 5b 6a 5d 20 3d 20 70 3b 0a 20 20 20 a[j] = p;.
6b40: 20 69 66 28 20 6a 3e 3d 6d 78 20 29 20 6d 78 20 if( j>=mx ) mx
6b50: 3d 20 6a 2b 31 3b 0a 20 20 7d 0a 20 20 70 20 3d = j+1;. }. p =
6b60: 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 0;. for(i=0; i
6b70: 3c 6d 78 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 70 <mx; i++){. p
6b80: 20 3d 20 67 65 6f 70 6f 6c 79 45 76 65 6e 74 4d = geopolyEventM
6b90: 65 72 67 65 28 61 5b 69 5d 2c 20 70 29 3b 0a 20 erge(a[i], p);.
6ba0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d }. return p;.}
6bb0: 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 77 ../*.** Merge tw
6bc0: 6f 20 6c 69 73 74 73 20 6f 66 20 73 6f 72 74 65 o lists of sorte
6bd0: 64 20 73 65 67 6d 65 6e 74 73 20 62 79 20 59 2c d segments by Y,
6be0: 20 61 6e 64 20 74 68 65 6e 20 62 79 20 43 2e 0a and then by C..
6bf0: 2a 2f 0a 73 74 61 74 69 63 20 47 65 6f 53 65 67 */.static GeoSeg
6c00: 6d 65 6e 74 20 2a 67 65 6f 70 6f 6c 79 53 65 67 ment *geopolySeg
6c10: 6d 65 6e 74 4d 65 72 67 65 28 47 65 6f 53 65 67 mentMerge(GeoSeg
6c20: 6d 65 6e 74 20 2a 70 4c 65 66 74 2c 20 47 65 6f ment *pLeft, Geo
6c30: 53 65 67 6d 65 6e 74 20 2a 70 52 69 67 68 74 29 Segment *pRight)
6c40: 7b 0a 20 20 47 65 6f 53 65 67 6d 65 6e 74 20 68 {. GeoSegment h
6c50: 65 61 64 2c 20 2a 70 4c 61 73 74 3b 0a 20 20 68 ead, *pLast;. h
6c60: 65 61 64 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 ead.pNext = 0;.
6c70: 20 70 4c 61 73 74 20 3d 20 26 68 65 61 64 3b 0a pLast = &head;.
6c80: 20 20 77 68 69 6c 65 28 20 70 52 69 67 68 74 20 while( pRight
6c90: 26 26 20 70 4c 65 66 74 20 29 7b 0a 20 20 20 20 && pLeft ){.
6ca0: 64 6f 75 62 6c 65 20 72 20 3d 20 70 52 69 67 68 double r = pRigh
6cb0: 74 2d 3e 79 20 2d 20 70 4c 65 66 74 2d 3e 79 3b t->y - pLeft->y;
6cc0: 0a 20 20 20 20 69 66 28 20 72 3d 3d 30 2e 30 20 . if( r==0.0
6cd0: 29 20 72 20 3d 20 70 52 69 67 68 74 2d 3e 43 20 ) r = pRight->C
6ce0: 2d 20 70 4c 65 66 74 2d 3e 43 3b 0a 20 20 20 20 - pLeft->C;.
6cf0: 69 66 28 20 72 3c 30 2e 30 20 29 7b 0a 20 20 20 if( r<0.0 ){.
6d00: 20 20 20 70 4c 61 73 74 2d 3e 70 4e 65 78 74 20 pLast->pNext
6d10: 3d 20 70 52 69 67 68 74 3b 0a 20 20 20 20 20 20 = pRight;.
6d20: 70 4c 61 73 74 20 3d 20 70 52 69 67 68 74 3b 0a pLast = pRight;.
6d30: 20 20 20 20 20 20 70 52 69 67 68 74 20 3d 20 70 pRight = p
6d40: 52 69 67 68 74 2d 3e 70 4e 65 78 74 3b 0a 20 20 Right->pNext;.
6d50: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 }else{. p
6d60: 4c 61 73 74 2d 3e 70 4e 65 78 74 20 3d 20 70 4c Last->pNext = pL
6d70: 65 66 74 3b 0a 20 20 20 20 20 20 70 4c 61 73 74 eft;. pLast
6d80: 20 3d 20 70 4c 65 66 74 3b 0a 20 20 20 20 20 20 = pLeft;.
6d90: 70 4c 65 66 74 20 3d 20 70 4c 65 66 74 2d 3e 70 pLeft = pLeft->p
6da0: 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a Next;. }. }.
6db0: 20 20 70 4c 61 73 74 2d 3e 70 4e 65 78 74 20 3d pLast->pNext =
6dc0: 20 70 52 69 67 68 74 20 3f 20 70 52 69 67 68 74 pRight ? pRight
6dd0: 20 3a 20 70 4c 65 66 74 3b 0a 20 20 72 65 74 75 : pLeft;. retu
6de0: 72 6e 20 68 65 61 64 2e 70 4e 65 78 74 3b 20 20 rn head.pNext;
6df0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 61 .}../*.** Sort a
6e00: 20 6c 69 73 74 20 6f 66 20 47 65 6f 53 65 67 6d list of GeoSegm
6e10: 65 6e 74 73 20 69 6e 20 6f 72 64 65 72 20 6f 66 ents in order of
6e20: 20 69 6e 63 72 65 61 73 69 6e 67 20 59 20 61 6e increasing Y an
6e30: 64 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20 6f d in the event o
6e40: 66 0a 2a 2a 20 61 20 74 69 65 2c 20 69 6e 63 72 f.** a tie, incr
6e50: 65 61 73 69 6e 67 20 43 20 28 73 6c 6f 70 65 29 easing C (slope)
6e60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 47 65 6f 53 ..*/.static GeoS
6e70: 65 67 6d 65 6e 74 20 2a 67 65 6f 70 6f 6c 79 53 egment *geopolyS
6e80: 6f 72 74 53 65 67 6d 65 6e 74 73 42 79 59 41 6e ortSegmentsByYAn
6e90: 64 43 28 47 65 6f 53 65 67 6d 65 6e 74 20 2a 70 dC(GeoSegment *p
6ea0: 4c 69 73 74 29 7b 0a 20 20 69 6e 74 20 6d 78 20 List){. int mx
6eb0: 3d 20 30 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 = 0;. int i;.
6ec0: 47 65 6f 53 65 67 6d 65 6e 74 20 2a 70 3b 0a 20 GeoSegment *p;.
6ed0: 20 47 65 6f 53 65 67 6d 65 6e 74 20 2a 61 5b 35 GeoSegment *a[5
6ee0: 30 5d 3b 0a 20 20 77 68 69 6c 65 28 20 70 4c 69 0];. while( pLi
6ef0: 73 74 20 29 7b 0a 20 20 20 20 70 20 3d 20 70 4c st ){. p = pL
6f00: 69 73 74 3b 0a 20 20 20 20 70 4c 69 73 74 20 3d ist;. pList =
6f10: 20 70 4c 69 73 74 2d 3e 70 4e 65 78 74 3b 0a 20 pList->pNext;.
6f20: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 30 3b p->pNext = 0;
6f30: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c . for(i=0; i<
6f40: 6d 78 20 26 26 20 61 5b 69 5d 3b 20 69 2b 2b 29 mx && a[i]; i++)
6f50: 7b 0a 20 20 20 20 20 20 70 20 3d 20 67 65 6f 70 {. p = geop
6f60: 6f 6c 79 53 65 67 6d 65 6e 74 4d 65 72 67 65 28 olySegmentMerge(
6f70: 61 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20 20 20 a[i], p);.
6f80: 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a a[i] = 0;. }.
6f90: 20 20 20 20 61 5b 69 5d 20 3d 20 70 3b 0a 20 20 a[i] = p;.
6fa0: 20 20 69 66 28 20 69 3e 3d 6d 78 20 29 20 6d 78 if( i>=mx ) mx
6fb0: 20 3d 20 69 2b 31 3b 0a 20 20 7d 0a 20 20 70 20 = i+1;. }. p
6fc0: 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 = 0;. for(i=0;
6fd0: 69 3c 6d 78 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 i<mx; i++){.
6fe0: 70 20 3d 20 67 65 6f 70 6f 6c 79 53 65 67 6d 65 p = geopolySegme
6ff0: 6e 74 4d 65 72 67 65 28 61 5b 69 5d 2c 20 70 29 ntMerge(a[i], p)
7000: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 ;. }. return p
7010: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 74 65 72 ;.}../*.** Deter
7020: 6d 69 6e 65 20 74 68 65 20 6f 76 65 72 6c 61 70 mine the overlap
7030: 20 62 65 74 77 65 65 6e 20 74 77 6f 20 70 6f 6c between two pol
7040: 79 67 6f 6e 73 0a 2a 2f 0a 73 74 61 74 69 63 20 ygons.*/.static
7050: 69 6e 74 20 67 65 6f 70 6f 6c 79 4f 76 65 72 6c int geopolyOverl
7060: 61 70 28 47 65 6f 50 6f 6c 79 20 2a 70 31 2c 20 ap(GeoPoly *p1,
7070: 47 65 6f 50 6f 6c 79 20 2a 70 32 29 7b 0a 20 20 GeoPoly *p2){.
7080: 69 6e 74 20 6e 56 65 72 74 65 78 20 3d 20 70 31 int nVertex = p1
7090: 2d 3e 6e 56 65 72 74 65 78 20 2b 20 70 32 2d 3e ->nVertex + p2->
70a0: 6e 56 65 72 74 65 78 20 2b 20 32 3b 0a 20 20 47 nVertex + 2;. G
70b0: 65 6f 4f 76 65 72 6c 61 70 20 2a 70 3b 0a 20 20 eoOverlap *p;.
70c0: 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 47 65 6f int nByte;. Geo
70d0: 45 76 65 6e 74 20 2a 70 54 68 69 73 45 76 65 6e Event *pThisEven
70e0: 74 3b 0a 20 20 64 6f 75 62 6c 65 20 72 58 3b 0a t;. double rX;.
70f0: 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 0a 20 20 int rc = 0;.
7100: 69 6e 74 20 6e 65 65 64 53 6f 72 74 20 3d 20 30 int needSort = 0
7110: 3b 0a 20 20 47 65 6f 53 65 67 6d 65 6e 74 20 2a ;. GeoSegment *
7120: 70 41 63 74 69 76 65 20 3d 20 30 3b 0a 20 20 47 pActive = 0;. G
7130: 65 6f 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 3b eoSegment *pSeg;
7140: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 . unsigned char
7150: 20 61 4f 76 65 72 6c 61 70 5b 34 5d 3b 0a 0a 20 aOverlap[4];..
7160: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 nByte = sizeof(
7170: 47 65 6f 45 76 65 6e 74 29 2a 6e 56 65 72 74 65 GeoEvent)*nVerte
7180: 78 2a 32 20 0a 20 20 20 20 20 20 20 20 20 20 20 x*2 .
7190: 2b 20 73 69 7a 65 6f 66 28 47 65 6f 53 65 67 6d + sizeof(GeoSegm
71a0: 65 6e 74 29 2a 6e 56 65 72 74 65 78 20 0a 20 20 ent)*nVertex .
71b0: 20 20 20 20 20 20 20 20 20 2b 20 73 69 7a 65 6f + sizeo
71c0: 66 28 47 65 6f 4f 76 65 72 6c 61 70 29 3b 0a 20 f(GeoOverlap);.
71d0: 20 70 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c p = sqlite3_mal
71e0: 6c 6f 63 28 20 6e 42 79 74 65 20 29 3b 0a 20 20 loc( nByte );.
71f0: 69 66 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72 if( p==0 ) retur
7200: 6e 20 2d 31 3b 0a 20 20 70 2d 3e 61 45 76 65 6e n -1;. p->aEven
7210: 74 20 3d 20 28 47 65 6f 45 76 65 6e 74 2a 29 26 t = (GeoEvent*)&
7220: 70 5b 31 5d 3b 0a 20 20 70 2d 3e 61 53 65 67 6d p[1];. p->aSegm
7230: 65 6e 74 20 3d 20 28 47 65 6f 53 65 67 6d 65 6e ent = (GeoSegmen
7240: 74 2a 29 26 70 2d 3e 61 45 76 65 6e 74 5b 6e 56 t*)&p->aEvent[nV
7250: 65 72 74 65 78 2a 32 5d 3b 0a 20 20 70 2d 3e 6e ertex*2];. p->n
7260: 45 76 65 6e 74 20 3d 20 70 2d 3e 6e 53 65 67 6d Event = p->nSegm
7270: 65 6e 74 20 3d 20 30 3b 0a 20 20 67 65 6f 70 6f ent = 0;. geopo
7280: 6c 79 41 64 64 53 65 67 6d 65 6e 74 73 28 70 2c lyAddSegments(p,
7290: 20 70 31 2c 20 31 29 3b 0a 20 20 67 65 6f 70 6f p1, 1);. geopo
72a0: 6c 79 41 64 64 53 65 67 6d 65 6e 74 73 28 70 2c lyAddSegments(p,
72b0: 20 70 32 2c 20 32 29 3b 0a 20 20 70 54 68 69 73 p2, 2);. pThis
72c0: 45 76 65 6e 74 20 3d 20 67 65 6f 70 6f 6c 79 53 Event = geopolyS
72d0: 6f 72 74 45 76 65 6e 74 73 42 79 58 28 70 2d 3e ortEventsByX(p->
72e0: 61 45 76 65 6e 74 2c 20 70 2d 3e 6e 45 76 65 6e aEvent, p->nEven
72f0: 74 29 3b 0a 20 20 72 58 20 3d 20 70 54 68 69 73 t);. rX = pThis
7300: 45 76 65 6e 74 2d 3e 78 3d 3d 30 2e 30 20 3f 20 Event->x==0.0 ?
7310: 2d 31 2e 30 20 3a 20 30 2e 30 3b 0a 20 20 6d 65 -1.0 : 0.0;. me
7320: 6d 73 65 74 28 61 4f 76 65 72 6c 61 70 2c 20 30 mset(aOverlap, 0
7330: 2c 20 73 69 7a 65 6f 66 28 61 4f 76 65 72 6c 61 , sizeof(aOverla
7340: 70 29 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 54 p));. while( pT
7350: 68 69 73 45 76 65 6e 74 20 29 7b 0a 20 20 20 20 hisEvent ){.
7360: 69 66 28 20 70 54 68 69 73 45 76 65 6e 74 2d 3e if( pThisEvent->
7370: 78 21 3d 72 58 20 29 7b 0a 20 20 20 20 20 20 47 x!=rX ){. G
7380: 65 6f 53 65 67 6d 65 6e 74 20 2a 70 50 72 65 76 eoSegment *pPrev
7390: 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 = 0;. int
73a0: 69 4d 61 73 6b 20 3d 20 30 3b 0a 20 20 20 20 20 iMask = 0;.
73b0: 20 47 45 4f 44 45 42 55 47 28 28 22 44 69 73 74 GEODEBUG(("Dist
73c0: 69 6e 63 74 20 58 3a 20 25 67 5c 6e 22 2c 20 70 inct X: %g\n", p
73d0: 54 68 69 73 45 76 65 6e 74 2d 3e 78 29 29 3b 0a ThisEvent->x));.
73e0: 20 20 20 20 20 20 72 58 20 3d 20 70 54 68 69 73 rX = pThis
73f0: 45 76 65 6e 74 2d 3e 78 3b 0a 20 20 20 20 20 20 Event->x;.
7400: 69 66 28 20 6e 65 65 64 53 6f 72 74 20 29 7b 0a if( needSort ){.
7410: 20 20 20 20 20 20 20 20 47 45 4f 44 45 42 55 47 GEODEBUG
7420: 28 28 22 53 4f 52 54 5c 6e 22 29 29 3b 0a 20 20 (("SORT\n"));.
7430: 20 20 20 20 20 20 70 41 63 74 69 76 65 20 3d 20 pActive =
7440: 67 65 6f 70 6f 6c 79 53 6f 72 74 53 65 67 6d 65 geopolySortSegme
7450: 6e 74 73 42 79 59 41 6e 64 43 28 70 41 63 74 69 ntsByYAndC(pActi
7460: 76 65 29 3b 0a 20 20 20 20 20 20 20 20 6e 65 65 ve);. nee
7470: 64 53 6f 72 74 20 3d 20 30 3b 0a 20 20 20 20 20 dSort = 0;.
7480: 20 7d 0a 20 20 20 20 20 20 66 6f 72 28 70 53 65 }. for(pSe
7490: 67 3d 70 41 63 74 69 76 65 3b 20 70 53 65 67 3b g=pActive; pSeg;
74a0: 20 70 53 65 67 3d 70 53 65 67 2d 3e 70 4e 65 78 pSeg=pSeg->pNex
74b0: 74 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 t){. if(
74c0: 70 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20 20 pPrev ){.
74d0: 20 20 20 69 66 28 20 70 50 72 65 76 2d 3e 79 21 if( pPrev->y!
74e0: 3d 70 53 65 67 2d 3e 79 20 29 7b 0a 20 20 20 20 =pSeg->y ){.
74f0: 20 20 20 20 20 20 20 20 47 45 4f 44 45 42 55 47 GEODEBUG
7500: 28 28 22 4d 41 53 4b 3a 20 25 64 5c 6e 22 2c 20 (("MASK: %d\n",
7510: 69 4d 61 73 6b 29 29 3b 0a 20 20 20 20 20 20 20 iMask));.
7520: 20 20 20 20 20 61 4f 76 65 72 6c 61 70 5b 69 4d aOverlap[iM
7530: 61 73 6b 5d 20 3d 20 31 3b 0a 20 20 20 20 20 20 ask] = 1;.
7540: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a }. }.
7550: 20 20 20 20 20 20 20 20 69 4d 61 73 6b 20 5e 3d iMask ^=
7560: 20 70 53 65 67 2d 3e 73 69 64 65 3b 0a 20 20 20 pSeg->side;.
7570: 20 20 20 20 20 70 50 72 65 76 20 3d 20 70 53 65 pPrev = pSe
7580: 67 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 g;. }.
7590: 20 70 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 pPrev = 0;.
75a0: 20 20 66 6f 72 28 70 53 65 67 3d 70 41 63 74 69 for(pSeg=pActi
75b0: 76 65 3b 20 70 53 65 67 3b 20 70 53 65 67 3d 70 ve; pSeg; pSeg=p
75c0: 53 65 67 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 Seg->pNext){.
75d0: 20 20 20 20 20 64 6f 75 62 6c 65 20 79 20 3d 20 double y =
75e0: 70 53 65 67 2d 3e 43 2a 72 58 20 2b 20 70 53 65 pSeg->C*rX + pSe
75f0: 67 2d 3e 42 3b 0a 20 20 20 20 20 20 20 20 47 45 g->B;. GE
7600: 4f 44 45 42 55 47 28 28 22 53 65 67 6d 65 6e 74 ODEBUG(("Segment
7610: 20 25 64 2e 25 64 20 25 67 2d 3e 25 67 5c 6e 22 %d.%d %g->%g\n"
7620: 2c 20 70 53 65 67 2d 3e 73 69 64 65 2c 20 70 53 , pSeg->side, pS
7630: 65 67 2d 3e 69 64 78 2c 20 70 53 65 67 2d 3e 79 eg->idx, pSeg->y
7640: 2c 20 79 29 29 3b 0a 20 20 20 20 20 20 20 20 70 , y));. p
7650: 53 65 67 2d 3e 79 20 3d 20 79 3b 0a 20 20 20 20 Seg->y = y;.
7660: 20 20 20 20 69 66 28 20 70 50 72 65 76 20 29 7b if( pPrev ){
7670: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70 . if( p
7680: 50 72 65 76 2d 3e 79 3e 70 53 65 67 2d 3e 79 20 Prev->y>pSeg->y
7690: 26 26 20 70 50 72 65 76 2d 3e 73 69 64 65 21 3d && pPrev->side!=
76a0: 70 53 65 67 2d 3e 73 69 64 65 20 29 7b 0a 20 20 pSeg->side ){.
76b0: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 31 rc = 1
76c0: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 47 45 ;. GE
76d0: 4f 44 45 42 55 47 28 28 22 43 72 6f 73 73 69 6e ODEBUG(("Crossin
76e0: 67 3a 20 25 64 2e 25 64 20 61 6e 64 20 25 64 2e g: %d.%d and %d.
76f0: 25 64 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 20 %d\n",.
7700: 20 20 20 20 20 20 20 20 20 20 20 70 50 72 65 76 pPrev
7710: 2d 3e 73 69 64 65 2c 20 70 50 72 65 76 2d 3e 69 ->side, pPrev->i
7720: 64 78 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 dx,.
7730: 20 20 20 20 20 20 20 20 70 53 65 67 2d 3e 73 69 pSeg->si
7740: 64 65 2c 20 70 53 65 67 2d 3e 69 64 78 29 29 3b de, pSeg->idx));
7750: 0a 20 20 20 20 20 20 20 20 20 20 20 20 67 6f 74 . got
7760: 6f 20 67 65 6f 70 6f 6c 79 4f 76 65 72 6c 61 70 o geopolyOverlap
7770: 44 6f 6e 65 3b 0a 20 20 20 20 20 20 20 20 20 20 Done;.
7780: 7d 65 6c 73 65 20 69 66 28 20 70 50 72 65 76 2d }else if( pPrev-
7790: 3e 79 21 3d 70 53 65 67 2d 3e 79 20 29 7b 0a 20 >y!=pSeg->y ){.
77a0: 20 20 20 20 20 20 20 20 20 20 20 47 45 4f 44 45 GEODE
77b0: 42 55 47 28 28 22 4d 41 53 4b 3a 20 25 64 5c 6e BUG(("MASK: %d\n
77c0: 22 2c 20 69 4d 61 73 6b 29 29 3b 0a 20 20 20 20 ", iMask));.
77d0: 20 20 20 20 20 20 20 20 61 4f 76 65 72 6c 61 70 aOverlap
77e0: 5b 69 4d 61 73 6b 5d 20 3d 20 31 3b 0a 20 20 20 [iMask] = 1;.
77f0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 }.
7800: 20 7d 0a 20 20 20 20 20 20 20 20 69 4d 61 73 6b }. iMask
7810: 20 5e 3d 20 70 53 65 67 2d 3e 73 69 64 65 3b 0a ^= pSeg->side;.
7820: 20 20 20 20 20 20 20 20 70 50 72 65 76 20 3d 20 pPrev =
7830: 70 53 65 67 3b 0a 20 20 20 20 20 20 7d 0a 20 20 pSeg;. }.
7840: 20 20 7d 0a 20 20 20 20 47 45 4f 44 45 42 55 47 }. GEODEBUG
7850: 28 28 22 25 73 20 25 64 2e 25 64 20 43 3d 25 67 (("%s %d.%d C=%g
7860: 20 42 3d 25 67 5c 6e 22 2c 0a 20 20 20 20 20 20 B=%g\n",.
7870: 70 54 68 69 73 45 76 65 6e 74 2d 3e 65 54 79 70 pThisEvent->eTyp
7880: 65 20 3f 20 22 52 4d 20 22 20 3a 20 22 41 44 44 e ? "RM " : "ADD
7890: 22 2c 0a 20 20 20 20 20 20 70 54 68 69 73 45 76 ",. pThisEv
78a0: 65 6e 74 2d 3e 70 53 65 67 2d 3e 73 69 64 65 2c ent->pSeg->side,
78b0: 20 70 54 68 69 73 45 76 65 6e 74 2d 3e 70 53 65 pThisEvent->pSe
78c0: 67 2d 3e 69 64 78 2c 0a 20 20 20 20 20 20 70 54 g->idx,. pT
78d0: 68 69 73 45 76 65 6e 74 2d 3e 70 53 65 67 2d 3e hisEvent->pSeg->
78e0: 43 2c 0a 20 20 20 20 20 20 70 54 68 69 73 45 76 C,. pThisEv
78f0: 65 6e 74 2d 3e 70 53 65 67 2d 3e 42 29 29 3b 0a ent->pSeg->B));.
7900: 20 20 20 20 69 66 28 20 70 54 68 69 73 45 76 65 if( pThisEve
7910: 6e 74 2d 3e 65 54 79 70 65 3d 3d 30 20 29 7b 0a nt->eType==0 ){.
7920: 20 20 20 20 20 20 2f 2a 20 41 64 64 20 61 20 73 /* Add a s
7930: 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 20 20 20 20 egment */.
7940: 70 53 65 67 20 3d 20 70 54 68 69 73 45 76 65 6e pSeg = pThisEven
7950: 74 2d 3e 70 53 65 67 3b 0a 20 20 20 20 20 20 70 t->pSeg;. p
7960: 53 65 67 2d 3e 79 20 3d 20 70 53 65 67 2d 3e 79 Seg->y = pSeg->y
7970: 30 3b 0a 20 20 20 20 20 20 70 53 65 67 2d 3e 70 0;. pSeg->p
7980: 4e 65 78 74 20 3d 20 70 41 63 74 69 76 65 3b 0a Next = pActive;.
7990: 20 20 20 20 20 20 70 41 63 74 69 76 65 20 3d 20 pActive =
79a0: 70 53 65 67 3b 0a 20 20 20 20 20 20 6e 65 65 64 pSeg;. need
79b0: 53 6f 72 74 20 3d 20 31 3b 0a 20 20 20 20 7d 65 Sort = 1;. }e
79c0: 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 52 65 lse{. /* Re
79d0: 6d 6f 76 65 20 61 20 73 65 67 6d 65 6e 74 20 2a move a segment *
79e0: 2f 0a 20 20 20 20 20 20 69 66 28 20 70 41 63 74 /. if( pAct
79f0: 69 76 65 3d 3d 70 54 68 69 73 45 76 65 6e 74 2d ive==pThisEvent-
7a00: 3e 70 53 65 67 20 29 7b 0a 20 20 20 20 20 20 20 >pSeg ){.
7a10: 20 70 41 63 74 69 76 65 20 3d 20 70 41 63 74 69 pActive = pActi
7a20: 76 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 ve->pNext;.
7a30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 }else{.
7a40: 66 6f 72 28 70 53 65 67 3d 70 41 63 74 69 76 65 for(pSeg=pActive
7a50: 3b 20 70 53 65 67 3b 20 70 53 65 67 3d 70 53 65 ; pSeg; pSeg=pSe
7a60: 67 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 g->pNext){.
7a70: 20 20 20 20 20 69 66 28 20 70 53 65 67 2d 3e 70 if( pSeg->p
7a80: 4e 65 78 74 3d 3d 70 54 68 69 73 45 76 65 6e 74 Next==pThisEvent
7a90: 2d 3e 70 53 65 67 20 29 7b 0a 20 20 20 20 20 20 ->pSeg ){.
7aa0: 20 20 20 20 20 20 70 53 65 67 2d 3e 70 4e 65 78 pSeg->pNex
7ab0: 74 20 3d 20 70 53 65 67 2d 3e 70 4e 65 78 74 2d t = pSeg->pNext-
7ac0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 >pNext;.
7ad0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 break;.
7ae0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d }. }
7af0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 . }. }.
7b00: 20 20 20 70 54 68 69 73 45 76 65 6e 74 20 3d 20 pThisEvent =
7b10: 70 54 68 69 73 45 76 65 6e 74 2d 3e 70 4e 65 78 pThisEvent->pNex
7b20: 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61 4f 76 t;. }. if( aOv
7b30: 65 72 6c 61 70 5b 33 5d 3d 3d 30 20 29 7b 0a 20 erlap[3]==0 ){.
7b40: 20 20 20 72 63 20 3d 20 30 3b 0a 20 20 7d 65 6c rc = 0;. }el
7b50: 73 65 20 69 66 28 20 61 4f 76 65 72 6c 61 70 5b se if( aOverlap[
7b60: 31 5d 21 3d 30 20 26 26 20 61 4f 76 65 72 6c 61 1]!=0 && aOverla
7b70: 70 5b 32 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 72 p[2]==0 ){. r
7b80: 63 20 3d 20 33 3b 0a 20 20 7d 65 6c 73 65 20 69 c = 3;. }else i
7b90: 66 28 20 61 4f 76 65 72 6c 61 70 5b 31 5d 3d 3d f( aOverlap[1]==
7ba0: 30 20 26 26 20 61 4f 76 65 72 6c 61 70 5b 32 5d 0 && aOverlap[2]
7bb0: 21 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 !=0 ){. rc =
7bc0: 32 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 61 2;. }else if( a
7bd0: 4f 76 65 72 6c 61 70 5b 31 5d 3d 3d 30 20 26 26 Overlap[1]==0 &&
7be0: 20 61 4f 76 65 72 6c 61 70 5b 32 5d 3d 3d 30 20 aOverlap[2]==0
7bf0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 34 3b 0a 20 ){. rc = 4;.
7c00: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d }else{. rc =
7c10: 20 31 3b 0a 20 20 7d 0a 0a 67 65 6f 70 6f 6c 79 1;. }..geopoly
7c20: 4f 76 65 72 6c 61 70 44 6f 6e 65 3a 0a 20 20 73 OverlapDone:. s
7c30: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a qlite3_free(p);.
7c40: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a return rc;.}..
7c50: 2f 2a 0a 2a 2a 20 53 51 4c 20 66 75 6e 63 74 69 /*.** SQL functi
7c60: 6f 6e 3a 20 20 20 20 67 65 6f 70 6f 6c 79 5f 6f on: geopoly_o
7c70: 76 65 72 6c 61 70 28 50 31 2c 50 32 29 0a 2a 2a verlap(P1,P2).**
7c80: 0a 2a 2a 20 44 65 74 65 72 6d 69 6e 65 20 77 68 .** Determine wh
7c90: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 50 31 20 ether or not P1
7ca0: 61 6e 64 20 50 32 20 6f 76 65 72 6c 61 70 2e 20 and P2 overlap.
7cb0: 52 65 74 75 72 6e 20 76 61 6c 75 65 3a 0a 2a 2a Return value:.**
7cc0: 0a 2a 2a 20 20 20 30 20 20 20 20 20 54 68 65 20 .** 0 The
7cd0: 74 77 6f 20 70 6f 6c 79 67 6f 6e 73 20 61 72 65 two polygons are
7ce0: 20 64 69 73 6a 6f 69 6e 74 0a 2a 2a 20 20 20 31 disjoint.** 1
7cf0: 20 20 20 20 20 54 68 65 79 20 6f 76 65 72 6c 61 They overla
7d00: 70 0a 2a 2a 20 20 20 32 20 20 20 20 20 50 31 20 p.** 2 P1
7d10: 69 73 20 63 6f 6d 70 6c 65 74 65 6c 79 20 63 6f is completely co
7d20: 6e 74 61 69 6e 65 64 20 77 69 74 68 69 6e 20 50 ntained within P
7d30: 32 0a 2a 2a 20 20 20 33 20 20 20 20 20 50 32 20 2.** 3 P2
7d40: 69 73 20 63 6f 6d 70 6c 65 74 65 6c 79 20 63 6f is completely co
7d50: 6e 74 61 69 6e 65 64 20 77 69 74 68 69 6e 20 50 ntained within P
7d60: 31 0a 2a 2a 20 20 20 34 20 20 20 20 20 50 31 20 1.** 4 P1
7d70: 61 6e 64 20 50 32 20 61 72 65 20 74 68 65 20 73 and P2 are the s
7d80: 61 6d 65 20 70 6f 6c 79 67 6f 6e 0a 2a 2a 20 20 ame polygon.**
7d90: 20 4e 55 4c 4c 20 20 45 69 74 68 65 72 20 50 31 NULL Either P1
7da0: 20 6f 72 20 50 32 20 6f 72 20 62 6f 74 68 20 61 or P2 or both a
7db0: 72 65 20 6e 6f 74 20 76 61 6c 69 64 20 70 6f 6c re not valid pol
7dc0: 79 67 6f 6e 73 0a 2a 2f 0a 73 74 61 74 69 63 20 ygons.*/.static
7dd0: 76 6f 69 64 20 67 65 6f 70 6f 6c 79 4f 76 65 72 void geopolyOver
7de0: 6c 61 70 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 lapFunc(. sqlit
7df0: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 e3_context *cont
7e00: 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c ext,. int argc,
7e10: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 . sqlite3_value
7e20: 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 47 65 6f **argv.){. Geo
7e30: 50 6f 6c 79 20 2a 70 31 20 3d 20 67 65 6f 70 6f Poly *p1 = geopo
7e40: 6c 79 46 75 6e 63 50 61 72 61 6d 28 63 6f 6e 74 lyFuncParam(cont
7e50: 65 78 74 2c 20 61 72 67 76 5b 30 5d 2c 20 30 29 ext, argv[0], 0)
7e60: 3b 0a 20 20 47 65 6f 50 6f 6c 79 20 2a 70 32 20 ;. GeoPoly *p2
7e70: 3d 20 67 65 6f 70 6f 6c 79 46 75 6e 63 50 61 72 = geopolyFuncPar
7e80: 61 6d 28 63 6f 6e 74 65 78 74 2c 20 61 72 67 76 am(context, argv
7e90: 5b 31 5d 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 [1], 0);. if( p
7ea0: 31 20 26 26 20 70 32 20 29 7b 0a 20 20 20 20 69 1 && p2 ){. i
7eb0: 6e 74 20 78 20 3d 20 67 65 6f 70 6f 6c 79 4f 76 nt x = geopolyOv
7ec0: 65 72 6c 61 70 28 70 31 2c 20 70 32 29 3b 0a 20 erlap(p1, p2);.
7ed0: 20 20 20 69 66 28 20 78 3c 30 20 29 7b 0a 20 20 if( x<0 ){.
7ee0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 sqlite3_resu
7ef0: 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 6d 28 63 lt_error_nomem(c
7f00: 6f 6e 74 65 78 74 29 3b 0a 20 20 20 20 7d 65 6c ontext);. }el
7f10: 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 se{. sqlite
7f20: 33 5f 72 65 73 75 6c 74 5f 69 6e 74 28 63 6f 6e 3_result_int(con
7f30: 74 65 78 74 2c 20 78 29 3b 0a 20 20 20 20 7d 0a text, x);. }.
7f40: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 }. sqlite3_fr
7f50: 65 65 28 70 31 29 3b 0a 20 20 73 71 6c 69 74 65 ee(p1);. sqlite
7f60: 33 5f 66 72 65 65 28 70 32 29 3b 0a 7d 0a 0a 2f 3_free(p2);.}../
7f70: 2a 0a 2a 2a 20 45 6e 61 62 6c 65 20 6f 72 20 64 *.** Enable or d
7f80: 69 73 61 62 6c 65 20 64 65 62 75 67 67 69 6e 67 isable debugging
7f90: 20 6f 75 74 70 75 74 0a 2a 2f 0a 73 74 61 74 69 output.*/.stati
7fa0: 63 20 76 6f 69 64 20 67 65 6f 70 6f 6c 79 44 65 c void geopolyDe
7fb0: 62 75 67 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 bugFunc(. sqlit
7fc0: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 e3_context *cont
7fd0: 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c ext,. int argc,
7fe0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 . sqlite3_value
7ff0: 20 2a 2a 61 72 67 76 0a 29 7b 0a 23 69 66 64 65 **argv.){.#ifde
8000: 66 20 47 45 4f 50 4f 4c 59 5f 45 4e 41 42 4c 45 f GEOPOLY_ENABLE
8010: 5f 44 45 42 55 47 0a 20 20 67 65 6f 5f 64 65 62 _DEBUG. geo_deb
8020: 75 67 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c ug = sqlite3_val
8030: 75 65 5f 69 6e 74 28 61 72 67 76 5b 30 5d 29 3b ue_int(argv[0]);
8040: 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 20 0a 2a .#endif.}../* .*
8050: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 * This function
8060: 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 is the implement
8070: 61 74 69 6f 6e 20 6f 66 20 62 6f 74 68 20 74 68 ation of both th
8080: 65 20 78 43 6f 6e 6e 65 63 74 20 61 6e 64 20 78 e xConnect and x
8090: 43 72 65 61 74 65 0a 2a 2a 20 6d 65 74 68 6f 64 Create.** method
80a0: 73 20 6f 66 20 74 68 65 20 67 65 6f 70 6f 6c 79 s of the geopoly
80b0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a virtual table..
80c0: 2a 2a 0a 2a 2a 20 20 20 61 72 67 76 5b 30 5d 20 **.** argv[0]
80d0: 20 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61 6d 65 -> module name
80e0: 0a 2a 2a 20 20 20 61 72 67 76 5b 31 5d 20 20 20 .** argv[1]
80f0: 2d 3e 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65 -> database name
8100: 0a 2a 2a 20 20 20 61 72 67 76 5b 32 5d 20 20 20 .** argv[2]
8110: 2d 3e 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a 2a -> table name.**
8120: 20 20 20 61 72 67 76 5b 2e 2e 2e 5d 20 2d 3e 20 argv[...] ->
8130: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e 2e 2e 0a column names....
8140: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 */.static int ge
8150: 6f 70 6f 6c 79 49 6e 69 74 28 0a 20 20 73 71 6c opolyInit(. sql
8160: 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 ite3 *db,
8170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8180: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e /* Database con
8190: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 nection */. voi
81a0: 64 20 2a 70 41 75 78 2c 20 20 20 20 20 20 20 20 d *pAux,
81b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
81c0: 20 2f 2a 20 4f 6e 65 20 6f 66 20 74 68 65 20 52 /* One of the R
81d0: 54 52 45 45 5f 43 4f 4f 52 44 5f 2a 20 63 6f 6e TREE_COORD_* con
81e0: 73 74 61 6e 74 73 20 2a 2f 0a 20 20 69 6e 74 20 stants */. int
81f0: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 argc, const char
8200: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 20 20 20 *const*argv,
8210: 2f 2a 20 50 61 72 61 6d 65 74 65 72 73 20 74 6f /* Parameters to
8220: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 73 74 CREATE TABLE st
8230: 61 74 65 6d 65 6e 74 20 2a 2f 0a 20 20 73 71 6c atement */. sql
8240: 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 ite3_vtab **ppVt
8250: 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 ab,
8260: 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 76 69 72 /* OUT: New vir
8270: 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 tual table */.
8280: 63 68 61 72 20 2a 2a 70 7a 45 72 72 2c 20 20 20 char **pzErr,
8290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
82a0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 45 72 72 6f /* OUT: Erro
82b0: 72 20 6d 65 73 73 61 67 65 2c 20 69 66 20 61 6e r message, if an
82c0: 79 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43 72 65 y */. int isCre
82d0: 61 74 65 20 20 20 20 20 20 20 20 20 20 20 20 20 ate
82e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 /* Tr
82f0: 75 65 20 66 6f 72 20 78 43 72 65 61 74 65 2c 20 ue for xCreate,
8300: 66 61 6c 73 65 20 66 6f 72 20 78 43 6f 6e 6e 65 false for xConne
8310: 63 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 ct */.){. int r
8320: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 c = SQLITE_OK;.
8330: 20 52 74 72 65 65 20 2a 70 52 74 72 65 65 3b 0a Rtree *pRtree;.
8340: 20 20 69 6e 74 20 6e 44 62 3b 20 20 20 20 20 20 int nDb;
8350: 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 /* Lengt
8360: 68 20 6f 66 20 73 74 72 69 6e 67 20 61 72 67 76 h of string argv
8370: 5b 31 5d 20 2a 2f 0a 20 20 69 6e 74 20 6e 4e 61 [1] */. int nNa
8380: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f me; /
8390: 2a 20 4c 65 6e 67 74 68 20 6f 66 20 73 74 72 69 * Length of stri
83a0: 6e 67 20 61 72 67 76 5b 32 5d 20 2a 2f 0a 20 20 ng argv[2] */.
83b0: 73 71 6c 69 74 65 33 5f 73 74 72 20 2a 70 53 71 sqlite3_str *pSq
83c0: 6c 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b l;. char *zSql;
83d0: 0a 20 20 69 6e 74 20 69 69 3b 0a 0a 20 20 73 71 . int ii;.. sq
83e0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 6f 6e 66 69 lite3_vtab_confi
83f0: 67 28 64 62 2c 20 53 51 4c 49 54 45 5f 56 54 41 g(db, SQLITE_VTA
8400: 42 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 53 55 50 B_CONSTRAINT_SUP
8410: 50 4f 52 54 2c 20 31 29 3b 0a 0a 20 20 2f 2a 20 PORT, 1);.. /*
8420: 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 73 71 6c Allocate the sql
8430: 69 74 65 33 5f 76 74 61 62 20 73 74 72 75 63 74 ite3_vtab struct
8440: 75 72 65 20 2a 2f 0a 20 20 6e 44 62 20 3d 20 28 ure */. nDb = (
8450: 69 6e 74 29 73 74 72 6c 65 6e 28 61 72 67 76 5b int)strlen(argv[
8460: 31 5d 29 3b 0a 20 20 6e 4e 61 6d 65 20 3d 20 28 1]);. nName = (
8470: 69 6e 74 29 73 74 72 6c 65 6e 28 61 72 67 76 5b int)strlen(argv[
8480: 32 5d 29 3b 0a 20 20 70 52 74 72 65 65 20 3d 20 2]);. pRtree =
8490: 28 52 74 72 65 65 20 2a 29 73 71 6c 69 74 65 33 (Rtree *)sqlite3
84a0: 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 52 _malloc(sizeof(R
84b0: 74 72 65 65 29 2b 6e 44 62 2b 6e 4e 61 6d 65 2b tree)+nDb+nName+
84c0: 32 29 3b 0a 20 20 69 66 28 20 21 70 52 74 72 65 2);. if( !pRtre
84d0: 65 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 e ){. return
84e0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 SQLITE_NOMEM;.
84f0: 7d 0a 20 20 6d 65 6d 73 65 74 28 70 52 74 72 65 }. memset(pRtre
8500: 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28 52 74 72 e, 0, sizeof(Rtr
8510: 65 65 29 2b 6e 44 62 2b 6e 4e 61 6d 65 2b 32 29 ee)+nDb+nName+2)
8520: 3b 0a 20 20 70 52 74 72 65 65 2d 3e 6e 42 75 73 ;. pRtree->nBus
8530: 79 20 3d 20 31 3b 0a 20 20 70 52 74 72 65 65 2d y = 1;. pRtree-
8540: 3e 62 61 73 65 2e 70 4d 6f 64 75 6c 65 20 3d 20 >base.pModule =
8550: 26 72 74 72 65 65 4d 6f 64 75 6c 65 3b 0a 20 20 &rtreeModule;.
8560: 70 52 74 72 65 65 2d 3e 7a 44 62 20 3d 20 28 63 pRtree->zDb = (c
8570: 68 61 72 20 2a 29 26 70 52 74 72 65 65 5b 31 5d har *)&pRtree[1]
8580: 3b 0a 20 20 70 52 74 72 65 65 2d 3e 7a 4e 61 6d ;. pRtree->zNam
8590: 65 20 3d 20 26 70 52 74 72 65 65 2d 3e 7a 44 62 e = &pRtree->zDb
85a0: 5b 6e 44 62 2b 31 5d 3b 0a 20 20 70 52 74 72 65 [nDb+1];. pRtre
85b0: 65 2d 3e 65 43 6f 6f 72 64 54 79 70 65 20 3d 20 e->eCoordType =
85c0: 52 54 52 45 45 5f 43 4f 4f 52 44 5f 52 45 41 4c RTREE_COORD_REAL
85d0: 33 32 3b 0a 20 20 70 52 74 72 65 65 2d 3e 6e 44 32;. pRtree->nD
85e0: 69 6d 20 3d 20 32 3b 0a 20 20 70 52 74 72 65 65 im = 2;. pRtree
85f0: 2d 3e 6e 44 69 6d 32 20 3d 20 34 3b 0a 20 20 6d ->nDim2 = 4;. m
8600: 65 6d 63 70 79 28 70 52 74 72 65 65 2d 3e 7a 44 emcpy(pRtree->zD
8610: 62 2c 20 61 72 67 76 5b 31 5d 2c 20 6e 44 62 29 b, argv[1], nDb)
8620: 3b 0a 20 20 6d 65 6d 63 70 79 28 70 52 74 72 65 ;. memcpy(pRtre
8630: 65 2d 3e 7a 4e 61 6d 65 2c 20 61 72 67 76 5b 32 e->zName, argv[2
8640: 5d 2c 20 6e 4e 61 6d 65 29 3b 0a 0a 0a 20 20 2f ], nName);... /
8650: 2a 20 43 72 65 61 74 65 2f 43 6f 6e 6e 65 63 74 * Create/Connect
8660: 20 74 6f 20 74 68 65 20 75 6e 64 65 72 6c 79 69 to the underlyi
8670: 6e 67 20 72 65 6c 61 74 69 6f 6e 61 6c 20 64 61 ng relational da
8680: 74 61 62 61 73 65 20 73 63 68 65 6d 61 2e 20 49 tabase schema. I
8690: 66 0a 20 20 2a 2a 20 74 68 61 74 20 69 73 20 73 f. ** that is s
86a0: 75 63 63 65 73 73 66 75 6c 2c 20 63 61 6c 6c 20 uccessful, call
86b0: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f sqlite3_declare_
86c0: 76 74 61 62 28 29 20 74 6f 20 63 6f 6e 66 69 67 vtab() to config
86d0: 75 72 65 0a 20 20 2a 2a 20 74 68 65 20 72 2d 74 ure. ** the r-t
86e0: 72 65 65 20 74 61 62 6c 65 20 73 63 68 65 6d 61 ree table schema
86f0: 2e 0a 20 20 2a 2f 0a 20 20 70 53 71 6c 20 3d 20 .. */. pSql =
8700: 73 71 6c 69 74 65 33 5f 73 74 72 5f 6e 65 77 28 sqlite3_str_new(
8710: 64 62 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 db);. sqlite3_s
8720: 74 72 5f 61 70 70 65 6e 64 66 28 70 53 71 6c 2c tr_appendf(pSql,
8730: 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 "CREATE TABLE x
8740: 28 5f 73 68 61 70 65 22 29 3b 0a 20 20 70 52 74 (_shape");. pRt
8750: 72 65 65 2d 3e 6e 41 75 78 20 3d 20 31 3b 20 20 ree->nAux = 1;
8760: 20 20 20 20 20 20 20 2f 2a 20 41 64 64 20 6f 6e /* Add on
8770: 65 20 66 6f 72 20 5f 73 68 61 70 65 20 2a 2f 0a e for _shape */.
8780: 20 20 70 52 74 72 65 65 2d 3e 6e 41 75 78 4e 6f pRtree->nAuxNo
8790: 74 4e 75 6c 6c 20 3d 20 31 3b 20 20 2f 2a 20 54 tNull = 1; /* T
87a0: 68 65 20 5f 73 68 61 70 65 20 63 6f 6c 75 6d 6e he _shape column
87b0: 20 69 73 20 61 6c 77 61 79 73 20 6e 6f 74 2d 6e is always not-n
87c0: 75 6c 6c 20 2a 2f 0a 20 20 66 6f 72 28 69 69 3d ull */. for(ii=
87d0: 33 3b 20 69 69 3c 61 72 67 63 3b 20 69 69 2b 2b 3; ii<argc; ii++
87e0: 29 7b 0a 20 20 20 20 70 52 74 72 65 65 2d 3e 6e ){. pRtree->n
87f0: 41 75 78 2b 2b 3b 0a 20 20 20 20 73 71 6c 69 74 Aux++;. sqlit
8800: 65 33 5f 73 74 72 5f 61 70 70 65 6e 64 66 28 70 e3_str_appendf(p
8810: 53 71 6c 2c 20 22 2c 25 73 22 2c 20 61 72 67 76 Sql, ",%s", argv
8820: 5b 69 69 5d 29 3b 0a 20 20 7d 0a 20 20 73 71 6c [ii]);. }. sql
8830: 69 74 65 33 5f 73 74 72 5f 61 70 70 65 6e 64 66 ite3_str_appendf
8840: 28 70 53 71 6c 2c 20 22 29 3b 22 29 3b 0a 20 20 (pSql, ");");.
8850: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 73 zSql = sqlite3_s
8860: 74 72 5f 66 69 6e 69 73 68 28 70 53 71 6c 29 3b tr_finish(pSql);
8870: 0a 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a . if( !zSql ){.
8880: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f rc = SQLITE_
8890: 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 20 69 NOMEM;. }else i
88a0: 66 28 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 28 72 f( SQLITE_OK!=(r
88b0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 64 65 63 6c c = sqlite3_decl
88c0: 61 72 65 5f 76 74 61 62 28 64 62 2c 20 7a 53 71 are_vtab(db, zSq
88d0: 6c 29 29 20 29 7b 0a 20 20 20 20 2a 70 7a 45 72 l)) ){. *pzEr
88e0: 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 r = sqlite3_mpri
88f0: 6e 74 66 28 22 25 73 22 2c 20 73 71 6c 69 74 65 ntf("%s", sqlite
8900: 33 5f 65 72 72 6d 73 67 28 64 62 29 29 3b 0a 20 3_errmsg(db));.
8910: 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 }. sqlite3_fre
8920: 65 28 7a 53 71 6c 29 3b 0a 20 20 69 66 28 20 72 e(zSql);. if( r
8930: 63 20 29 20 67 6f 74 6f 20 67 65 6f 70 6f 6c 79 c ) goto geopoly
8940: 49 6e 69 74 5f 66 61 69 6c 3b 0a 20 20 70 52 74 Init_fail;. pRt
8950: 72 65 65 2d 3e 6e 42 79 74 65 73 50 65 72 43 65 ree->nBytesPerCe
8960: 6c 6c 20 3d 20 38 20 2b 20 70 52 74 72 65 65 2d ll = 8 + pRtree-
8970: 3e 6e 44 69 6d 32 2a 34 3b 0a 0a 20 20 2f 2a 20 >nDim2*4;.. /*
8980: 46 69 67 75 72 65 20 6f 75 74 20 74 68 65 20 6e Figure out the n
8990: 6f 64 65 20 73 69 7a 65 20 74 6f 20 75 73 65 2e ode size to use.
89a0: 20 2a 2f 0a 20 20 72 63 20 3d 20 67 65 74 4e 6f */. rc = getNo
89b0: 64 65 53 69 7a 65 28 64 62 2c 20 70 52 74 72 65 deSize(db, pRtre
89c0: 65 2c 20 69 73 43 72 65 61 74 65 2c 20 70 7a 45 e, isCreate, pzE
89d0: 72 72 29 3b 0a 20 20 69 66 28 20 72 63 20 29 20 rr);. if( rc )
89e0: 67 6f 74 6f 20 67 65 6f 70 6f 6c 79 49 6e 69 74 goto geopolyInit
89f0: 5f 66 61 69 6c 3b 0a 20 20 72 63 20 3d 20 72 74 _fail;. rc = rt
8a00: 72 65 65 53 71 6c 49 6e 69 74 28 70 52 74 72 65 reeSqlInit(pRtre
8a10: 65 2c 20 64 62 2c 20 61 72 67 76 5b 31 5d 2c 20 e, db, argv[1],
8a20: 61 72 67 76 5b 32 5d 2c 20 69 73 43 72 65 61 74 argv[2], isCreat
8a30: 65 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a e);. if( rc ){.
8a40: 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c *pzErr = sql
8a50: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 ite3_mprintf("%s
8a60: 22 2c 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 ", sqlite3_errms
8a70: 67 28 64 62 29 29 3b 0a 20 20 20 20 67 6f 74 6f g(db));. goto
8a80: 20 67 65 6f 70 6f 6c 79 49 6e 69 74 5f 66 61 69 geopolyInit_fai
8a90: 6c 3b 0a 20 20 7d 0a 0a 20 20 2a 70 70 56 74 61 l;. }.. *ppVta
8aa0: 62 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 b = (sqlite3_vta
8ab0: 62 20 2a 29 70 52 74 72 65 65 3b 0a 20 20 72 65 b *)pRtree;. re
8ac0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a turn SQLITE_OK;.
8ad0: 0a 67 65 6f 70 6f 6c 79 49 6e 69 74 5f 66 61 69 .geopolyInit_fai
8ae0: 6c 3a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c l:. if( rc==SQL
8af0: 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 53 51 ITE_OK ) rc = SQ
8b00: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 61 73 LITE_ERROR;. as
8b10: 73 65 72 74 28 20 2a 70 70 56 74 61 62 3d 3d 30 sert( *ppVtab==0
8b20: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 52 );. assert( pR
8b30: 74 72 65 65 2d 3e 6e 42 75 73 79 3d 3d 31 20 29 tree->nBusy==1 )
8b40: 3b 0a 20 20 72 74 72 65 65 52 65 6c 65 61 73 65 ;. rtreeRelease
8b50: 28 70 52 74 72 65 65 29 3b 0a 20 20 72 65 74 75 (pRtree);. retu
8b60: 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 20 0a 2a rn rc;.}.../* .*
8b70: 2a 20 47 45 4f 50 4f 4c 59 20 76 69 72 74 75 61 * GEOPOLY virtua
8b80: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 l table module x
8b90: 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a Create method..*
8ba0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 6f /.static int geo
8bb0: 70 6f 6c 79 43 72 65 61 74 65 28 0a 20 20 73 71 polyCreate(. sq
8bc0: 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 lite3 *db,. voi
8bd0: 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 d *pAux,. int a
8be0: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 rgc, const char
8bf0: 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 *const*argv,. s
8c00: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 qlite3_vtab **pp
8c10: 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 Vtab,. char **p
8c20: 7a 45 72 72 0a 29 7b 0a 20 20 72 65 74 75 72 6e zErr.){. return
8c30: 20 67 65 6f 70 6f 6c 79 49 6e 69 74 28 64 62 2c geopolyInit(db,
8c40: 20 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 pAux, argc, arg
8c50: 76 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 v, ppVtab, pzErr
8c60: 2c 20 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 , 1);.}../* .**
8c70: 47 45 4f 50 4f 4c 59 20 76 69 72 74 75 61 6c 20 GEOPOLY virtual
8c80: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f table module xCo
8c90: 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f nnect method..*/
8ca0: 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 6f 70 .static int geop
8cb0: 6f 6c 79 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 olyConnect(. sq
8cc0: 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 lite3 *db,. voi
8cd0: 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 d *pAux,. int a
8ce0: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 rgc, const char
8cf0: 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 *const*argv,. s
8d00: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 qlite3_vtab **pp
8d10: 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 Vtab,. char **p
8d20: 7a 45 72 72 0a 29 7b 0a 20 20 72 65 74 75 72 6e zErr.){. return
8d30: 20 67 65 6f 70 6f 6c 79 49 6e 69 74 28 64 62 2c geopolyInit(db,
8d40: 20 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 pAux, argc, arg
8d50: 76 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 v, ppVtab, pzErr
8d60: 2c 20 30 29 3b 0a 7d 0a 0a 0a 2f 2a 20 0a 2a 2a , 0);.}.../* .**
8d70: 20 47 45 4f 50 4f 4c 59 20 76 69 72 74 75 61 6c GEOPOLY virtual
8d80: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 46 table module xF
8d90: 69 6c 74 65 72 20 6d 65 74 68 6f 64 2e 0a 2a 2a ilter method..**
8da0: 0a 2a 2a 20 51 75 65 72 79 20 70 6c 61 6e 73 3a .** Query plans:
8db0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 31 20 20 20 .**.** 1
8dc0: 20 20 20 20 20 20 72 6f 77 69 64 20 6c 6f 6f 6b rowid look
8dd0: 75 70 0a 2a 2a 20 20 20 20 20 20 32 20 20 20 20 up.** 2
8de0: 20 20 20 20 20 73 65 61 72 63 68 20 66 6f 72 20 search for
8df0: 6f 62 6a 65 63 74 73 20 6f 76 65 72 6c 61 70 70 objects overlapp
8e00: 69 6e 67 20 74 68 65 20 73 61 6d 65 20 62 6f 75 ing the same bou
8e10: 6e 64 69 6e 67 20 62 6f 78 0a 2a 2a 20 20 20 20 nding box.**
8e20: 20 20 20 20 20 20 20 20 20 20 20 20 74 68 61 74 that
8e30: 20 63 6f 6e 74 61 69 6e 73 20 70 6f 6c 79 67 6f contains polygo
8e40: 6e 20 61 72 67 76 5b 30 5d 0a 2a 2a 20 20 20 20 n argv[0].**
8e50: 20 20 33 20 20 20 20 20 20 20 20 20 73 65 61 72 3 sear
8e60: 63 68 20 66 6f 72 20 6f 62 6a 65 63 74 73 20 6f ch for objects o
8e70: 76 65 72 6c 61 70 70 69 6e 67 20 74 68 65 20 73 verlapping the s
8e80: 61 6d 65 20 62 6f 75 6e 64 69 6e 67 20 62 6f 78 ame bounding box
8e90: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 .**
8ea0: 20 20 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 that contains
8eb0: 20 70 6f 6c 79 67 6f 6e 20 61 72 67 76 5b 30 5d polygon argv[0]
8ec0: 0a 2a 2a 20 20 20 20 20 20 34 20 20 20 20 20 20 .** 4
8ed0: 20 20 20 66 75 6c 6c 20 74 61 62 6c 65 20 73 63 full table sc
8ee0: 61 6e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 an.*/.static int
8ef0: 20 67 65 6f 70 6f 6c 79 46 69 6c 74 65 72 28 0a geopolyFilter(.
8f00: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 sqlite3_vtab_c
8f10: 75 72 73 6f 72 20 2a 70 56 74 61 62 43 75 72 73 ursor *pVtabCurs
8f20: 6f 72 2c 20 20 20 20 20 2f 2a 20 54 68 65 20 63 or, /* The c
8f30: 75 72 73 6f 72 20 74 6f 20 69 6e 69 74 69 61 6c ursor to initial
8f40: 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78 ize */. int idx
8f50: 4e 75 6d 2c 20 20 20 20 20 20 20 20 20 20 20 20 Num,
8f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
8f70: 2a 20 51 75 65 72 79 20 70 6c 61 6e 20 2a 2f 0a * Query plan */.
8f80: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 const char *id
8f90: 78 53 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 xStr,
8fa0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 74 20 55 /* Not U
8fb0: 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 sed */. int arg
8fc0: 63 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 c, sqlite3_value
8fd0: 20 2a 2a 61 72 67 76 20 20 20 20 20 20 20 20 2f **argv /
8fe0: 2a 20 50 61 72 61 6d 65 74 65 72 73 20 74 6f 20 * Parameters to
8ff0: 74 68 65 20 71 75 65 72 79 20 70 6c 61 6e 20 2a the query plan *
9000: 2f 0a 29 7b 0a 20 20 52 74 72 65 65 20 2a 70 52 /.){. Rtree *pR
9010: 74 72 65 65 20 3d 20 28 52 74 72 65 65 20 2a 29 tree = (Rtree *)
9020: 70 56 74 61 62 43 75 72 73 6f 72 2d 3e 70 56 74 pVtabCursor->pVt
9030: 61 62 3b 0a 20 20 52 74 72 65 65 43 75 72 73 6f ab;. RtreeCurso
9040: 72 20 2a 70 43 73 72 20 3d 20 28 52 74 72 65 65 r *pCsr = (Rtree
9050: 43 75 72 73 6f 72 20 2a 29 70 56 74 61 62 43 75 Cursor *)pVtabCu
9060: 72 73 6f 72 3b 0a 20 20 52 74 72 65 65 4e 6f 64 rsor;. RtreeNod
9070: 65 20 2a 70 52 6f 6f 74 20 3d 20 30 3b 0a 20 20 e *pRoot = 0;.
9080: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f int rc = SQLITE_
9090: 4f 4b 3b 0a 20 20 69 6e 74 20 69 43 65 6c 6c 20 OK;. int iCell
90a0: 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 = 0;. sqlite3_s
90b0: 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 0a 20 20 72 tmt *pStmt;.. r
90c0: 74 72 65 65 52 65 66 65 72 65 6e 63 65 28 70 52 treeReference(pR
90d0: 74 72 65 65 29 3b 0a 0a 20 20 2f 2a 20 52 65 73 tree);.. /* Res
90e0: 65 74 20 74 68 65 20 63 75 72 73 6f 72 20 74 6f et the cursor to
90f0: 20 74 68 65 20 73 61 6d 65 20 73 74 61 74 65 20 the same state
9100: 61 73 20 72 74 72 65 65 4f 70 65 6e 28 29 20 6c as rtreeOpen() l
9110: 65 61 76 65 73 20 69 74 20 69 6e 2e 20 2a 2f 0a eaves it in. */.
9120: 20 20 66 72 65 65 43 75 72 73 6f 72 43 6f 6e 73 freeCursorCons
9130: 74 72 61 69 6e 74 73 28 70 43 73 72 29 3b 0a 20 traints(pCsr);.
9140: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 sqlite3_free(pC
9150: 73 72 2d 3e 61 50 6f 69 6e 74 29 3b 0a 20 20 70 sr->aPoint);. p
9160: 53 74 6d 74 20 3d 20 70 43 73 72 2d 3e 70 52 65 Stmt = pCsr->pRe
9170: 61 64 41 75 78 3b 0a 20 20 6d 65 6d 73 65 74 28 adAux;. memset(
9180: 70 43 73 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 pCsr, 0, sizeof(
9190: 52 74 72 65 65 43 75 72 73 6f 72 29 29 3b 0a 20 RtreeCursor));.
91a0: 20 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 pCsr->base.pVta
91b0: 62 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 b = (sqlite3_vta
91c0: 62 2a 29 70 52 74 72 65 65 3b 0a 20 20 70 43 73 b*)pRtree;. pCs
91d0: 72 2d 3e 70 52 65 61 64 41 75 78 20 3d 20 70 53 r->pReadAux = pS
91e0: 74 6d 74 3b 0a 0a 20 20 70 43 73 72 2d 3e 69 53 tmt;.. pCsr->iS
91f0: 74 72 61 74 65 67 79 20 3d 20 69 64 78 4e 75 6d trategy = idxNum
9200: 3b 0a 20 20 69 66 28 20 69 64 78 4e 75 6d 3d 3d ;. if( idxNum==
9210: 31 20 29 7b 0a 20 20 20 20 2f 2a 20 53 70 65 63 1 ){. /* Spec
9220: 69 61 6c 20 63 61 73 65 20 2d 20 6c 6f 6f 6b 75 ial case - looku
9230: 70 20 62 79 20 72 6f 77 69 64 2e 20 2a 2f 0a 20 p by rowid. */.
9240: 20 20 20 52 74 72 65 65 4e 6f 64 65 20 2a 70 4c RtreeNode *pL
9250: 65 61 66 3b 20 20 20 20 20 20 20 20 2f 2a 20 4c eaf; /* L
9260: 65 61 66 20 6f 6e 20 77 68 69 63 68 20 74 68 65 eaf on which the
9270: 20 72 65 71 75 69 72 65 64 20 63 65 6c 6c 20 72 required cell r
9280: 65 73 69 64 65 73 20 2a 2f 0a 20 20 20 20 52 74 esides */. Rt
9290: 72 65 65 53 65 61 72 63 68 50 6f 69 6e 74 20 2a reeSearchPoint *
92a0: 70 3b 20 20 20 20 20 2f 2a 20 53 65 61 72 63 68 p; /* Search
92b0: 20 70 6f 69 6e 74 20 66 6f 72 20 74 68 65 20 6c point for the l
92c0: 65 61 66 20 2a 2f 0a 20 20 20 20 69 36 34 20 69 eaf */. i64 i
92d0: 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f Rowid = sqlite3_
92e0: 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 72 67 76 value_int64(argv
92f0: 5b 30 5d 29 3b 0a 20 20 20 20 69 36 34 20 69 4e [0]);. i64 iN
9300: 6f 64 65 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 ode = 0;. rc
9310: 3d 20 66 69 6e 64 4c 65 61 66 4e 6f 64 65 28 70 = findLeafNode(p
9320: 52 74 72 65 65 2c 20 69 52 6f 77 69 64 2c 20 26 Rtree, iRowid, &
9330: 70 4c 65 61 66 2c 20 26 69 4e 6f 64 65 29 3b 0a pLeaf, &iNode);.
9340: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 if( rc==SQLI
9350: 54 45 5f 4f 4b 20 26 26 20 70 4c 65 61 66 21 3d TE_OK && pLeaf!=
9360: 30 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 72 0 ){. p = r
9370: 74 72 65 65 53 65 61 72 63 68 50 6f 69 6e 74 4e treeSearchPointN
9380: 65 77 28 70 43 73 72 2c 20 52 54 52 45 45 5f 5a ew(pCsr, RTREE_Z
9390: 45 52 4f 2c 20 30 29 3b 0a 20 20 20 20 20 20 61 ERO, 0);. a
93a0: 73 73 65 72 74 28 20 70 21 3d 30 20 29 3b 20 20 ssert( p!=0 );
93b0: 2f 2a 20 41 6c 77 61 79 73 20 72 65 74 75 72 6e /* Always return
93c0: 73 20 70 43 73 72 2d 3e 73 50 6f 69 6e 74 20 2a s pCsr->sPoint *
93d0: 2f 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61 4e /. pCsr->aN
93e0: 6f 64 65 5b 30 5d 20 3d 20 70 4c 65 61 66 3b 0a ode[0] = pLeaf;.
93f0: 20 20 20 20 20 20 70 2d 3e 69 64 20 3d 20 69 4e p->id = iN
9400: 6f 64 65 3b 0a 20 20 20 20 20 20 70 2d 3e 65 57 ode;. p->eW
9410: 69 74 68 69 6e 20 3d 20 50 41 52 54 4c 59 5f 57 ithin = PARTLY_W
9420: 49 54 48 49 4e 3b 0a 20 20 20 20 20 20 72 63 20 ITHIN;. rc
9430: 3d 20 6e 6f 64 65 52 6f 77 69 64 49 6e 64 65 78 = nodeRowidIndex
9440: 28 70 52 74 72 65 65 2c 20 70 4c 65 61 66 2c 20 (pRtree, pLeaf,
9450: 69 52 6f 77 69 64 2c 20 26 69 43 65 6c 6c 29 3b iRowid, &iCell);
9460: 0a 20 20 20 20 20 20 70 2d 3e 69 43 65 6c 6c 20 . p->iCell
9470: 3d 20 28 75 38 29 69 43 65 6c 6c 3b 0a 20 20 20 = (u8)iCell;.
9480: 20 20 20 52 54 52 45 45 5f 51 55 45 55 45 5f 54 RTREE_QUEUE_T
9490: 52 41 43 45 28 70 43 73 72 2c 20 22 50 55 53 48 RACE(pCsr, "PUSH
94a0: 2d 46 31 3a 22 29 3b 0a 20 20 20 20 7d 65 6c 73 -F1:");. }els
94b0: 65 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61 e{. pCsr->a
94c0: 74 45 4f 46 20 3d 20 31 3b 0a 20 20 20 20 7d 0a tEOF = 1;. }.
94d0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 }else{. /*
94e0: 4e 6f 72 6d 61 6c 20 63 61 73 65 20 2d 20 72 2d Normal case - r-
94f0: 74 72 65 65 20 73 63 61 6e 2e 20 53 65 74 20 75 tree scan. Set u
9500: 70 20 74 68 65 20 52 74 72 65 65 43 75 72 73 6f p the RtreeCurso
9510: 72 2e 61 43 6f 6e 73 74 72 61 69 6e 74 20 61 72 r.aConstraint ar
9520: 72 61 79 20 0a 20 20 20 20 2a 2a 20 77 69 74 68 ray . ** with
9530: 20 74 68 65 20 63 6f 6e 66 69 67 75 72 65 64 20 the configured
9540: 63 6f 6e 73 74 72 61 69 6e 74 73 2e 20 0a 20 20 constraints. .
9550: 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 6e 6f */. rc = no
9560: 64 65 41 63 71 75 69 72 65 28 70 52 74 72 65 65 deAcquire(pRtree
9570: 2c 20 31 2c 20 30 2c 20 26 70 52 6f 6f 74 29 3b , 1, 0, &pRoot);
9580: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c . if( rc==SQL
9590: 49 54 45 5f 4f 4b 20 26 26 20 69 64 78 4e 75 6d ITE_OK && idxNum
95a0: 3c 3d 33 20 29 7b 0a 20 20 20 20 20 20 52 74 72 <=3 ){. Rtr
95b0: 65 65 43 6f 6f 72 64 20 62 62 6f 78 5b 34 5d 3b eeCoord bbox[4];
95c0: 0a 20 20 20 20 20 20 52 74 72 65 65 43 6f 6e 73 . RtreeCons
95d0: 74 72 61 69 6e 74 20 2a 70 3b 0a 20 20 20 20 20 traint *p;.
95e0: 20 61 73 73 65 72 74 28 20 61 72 67 63 3d 3d 31 assert( argc==1
95f0: 20 29 3b 0a 20 20 20 20 20 20 67 65 6f 70 6f 6c );. geopol
9600: 79 42 42 6f 78 28 30 2c 20 61 72 67 76 5b 30 5d yBBox(0, argv[0]
9610: 2c 20 62 62 6f 78 2c 20 26 72 63 29 3b 0a 20 20 , bbox, &rc);.
9620: 20 20 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 if( rc ){.
9630: 20 20 20 20 20 20 67 6f 74 6f 20 67 65 6f 70 6f goto geopo
9640: 6c 79 5f 66 69 6c 74 65 72 5f 65 6e 64 3b 0a 20 ly_filter_end;.
9650: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 43 73 }. pCs
9660: 72 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 20 3d r->aConstraint =
9670: 20 70 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c p = sqlite3_mal
9680: 6c 6f 63 28 73 69 7a 65 6f 66 28 52 74 72 65 65 loc(sizeof(Rtree
9690: 43 6f 6e 73 74 72 61 69 6e 74 29 2a 34 29 3b 0a Constraint)*4);.
96a0: 20 20 20 20 20 20 70 43 73 72 2d 3e 6e 43 6f 6e pCsr->nCon
96b0: 73 74 72 61 69 6e 74 20 3d 20 34 3b 0a 20 20 20 straint = 4;.
96c0: 20 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a 20 if( p==0 ){.
96d0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 rc = SQLI
96e0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 TE_NOMEM;.
96f0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6d }else{. m
9700: 65 6d 73 65 74 28 70 43 73 72 2d 3e 61 43 6f 6e emset(pCsr->aCon
9710: 73 74 72 61 69 6e 74 2c 20 30 2c 20 73 69 7a 65 straint, 0, size
9720: 6f 66 28 52 74 72 65 65 43 6f 6e 73 74 72 61 69 of(RtreeConstrai
9730: 6e 74 29 2a 34 29 3b 0a 20 20 20 20 20 20 20 20 nt)*4);.
9740: 6d 65 6d 73 65 74 28 70 43 73 72 2d 3e 61 6e 51 memset(pCsr->anQ
9750: 75 65 75 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28 ueue, 0, sizeof(
9760: 75 33 32 29 2a 28 70 52 74 72 65 65 2d 3e 69 44 u32)*(pRtree->iD
9770: 65 70 74 68 20 2b 20 31 29 29 3b 0a 20 20 20 20 epth + 1));.
9780: 20 20 20 20 69 66 28 20 69 64 78 4e 75 6d 3d 3d if( idxNum==
9790: 32 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2 ){. /
97a0: 2a 20 4f 76 65 72 6c 61 70 20 71 75 65 72 79 20 * Overlap query
97b0: 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e */. p->
97c0: 6f 70 20 3d 20 27 42 27 3b 0a 20 20 20 20 20 20 op = 'B';.
97d0: 20 20 20 20 70 2d 3e 69 43 6f 6f 72 64 20 3d 20 p->iCoord =
97e0: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 0;. p->
97f0: 75 2e 72 56 61 6c 75 65 20 3d 20 62 62 6f 78 5b u.rValue = bbox[
9800: 31 5d 2e 66 3b 0a 20 20 20 20 20 20 20 20 20 20 1].f;.
9810: 70 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 70 p++;. p
9820: 2d 3e 6f 70 20 3d 20 27 44 27 3b 0a 20 20 20 20 ->op = 'D';.
9830: 20 20 20 20 20 20 70 2d 3e 69 43 6f 6f 72 64 20 p->iCoord
9840: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 70 = 1;. p
9850: 2d 3e 75 2e 72 56 61 6c 75 65 20 3d 20 62 62 6f ->u.rValue = bbo
9860: 78 5b 30 5d 2e 66 3b 0a 20 20 20 20 20 20 20 20 x[0].f;.
9870: 20 20 70 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 p++;.
9880: 20 70 2d 3e 6f 70 20 3d 20 27 42 27 3b 0a 20 20 p->op = 'B';.
9890: 20 20 20 20 20 20 20 20 70 2d 3e 69 43 6f 6f 72 p->iCoor
98a0: 64 20 3d 20 32 3b 0a 20 20 20 20 20 20 20 20 20 d = 2;.
98b0: 20 70 2d 3e 75 2e 72 56 61 6c 75 65 20 3d 20 62 p->u.rValue = b
98c0: 62 6f 78 5b 33 5d 2e 66 3b 0a 20 20 20 20 20 20 box[3].f;.
98d0: 20 20 20 20 70 2b 2b 3b 0a 20 20 20 20 20 20 20 p++;.
98e0: 20 20 20 70 2d 3e 6f 70 20 3d 20 27 44 27 3b 0a p->op = 'D';.
98f0: 20 20 20 20 20 20 20 20 20 20 70 2d 3e 69 43 6f p->iCo
9900: 6f 72 64 20 3d 20 33 3b 0a 20 20 20 20 20 20 20 ord = 3;.
9910: 20 20 20 70 2d 3e 75 2e 72 56 61 6c 75 65 20 3d p->u.rValue =
9920: 20 62 62 6f 78 5b 32 5d 2e 66 3b 0a 20 20 20 20 bbox[2].f;.
9930: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 }else{.
9940: 20 20 20 20 20 2f 2a 20 57 69 74 68 69 6e 20 71 /* Within q
9950: 75 65 72 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 uery */.
9960: 20 20 70 2d 3e 6f 70 20 3d 20 27 44 27 3b 0a 20 p->op = 'D';.
9970: 20 20 20 20 20 20 20 20 20 70 2d 3e 69 43 6f 6f p->iCoo
9980: 72 64 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 rd = 0;.
9990: 20 20 70 2d 3e 75 2e 72 56 61 6c 75 65 20 3d 20 p->u.rValue =
99a0: 62 62 6f 78 5b 30 5d 2e 66 3b 0a 20 20 20 20 20 bbox[0].f;.
99b0: 20 20 20 20 20 70 2b 2b 3b 0a 20 20 20 20 20 20 p++;.
99c0: 20 20 20 20 70 2d 3e 6f 70 20 3d 20 27 42 27 3b p->op = 'B';
99d0: 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 69 43 . p->iC
99e0: 6f 6f 72 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 oord = 1;.
99f0: 20 20 20 20 70 2d 3e 75 2e 72 56 61 6c 75 65 20 p->u.rValue
9a00: 3d 20 62 62 6f 78 5b 31 5d 2e 66 3b 0a 20 20 20 = bbox[1].f;.
9a10: 20 20 20 20 20 20 20 70 2b 2b 3b 0a 20 20 20 20 p++;.
9a20: 20 20 20 20 20 20 70 2d 3e 6f 70 20 3d 20 27 44 p->op = 'D
9a30: 27 3b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e ';. p->
9a40: 69 43 6f 6f 72 64 20 3d 20 32 3b 0a 20 20 20 20 iCoord = 2;.
9a50: 20 20 20 20 20 20 70 2d 3e 75 2e 72 56 61 6c 75 p->u.rValu
9a60: 65 20 3d 20 62 62 6f 78 5b 32 5d 2e 66 3b 0a 20 e = bbox[2].f;.
9a70: 20 20 20 20 20 20 20 20 20 70 2b 2b 3b 0a 20 20 p++;.
9a80: 20 20 20 20 20 20 20 20 70 2d 3e 6f 70 20 3d 20 p->op =
9a90: 27 42 27 3b 0a 20 20 20 20 20 20 20 20 20 20 70 'B';. p
9aa0: 2d 3e 69 43 6f 6f 72 64 20 3d 20 33 3b 0a 20 20 ->iCoord = 3;.
9ab0: 20 20 20 20 20 20 20 20 70 2d 3e 75 2e 72 56 61 p->u.rVa
9ac0: 6c 75 65 20 3d 20 62 62 6f 78 5b 33 5d 2e 66 3b lue = bbox[3].f;
9ad0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 . }.
9ae0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 }. }. if(
9af0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 rc==SQLITE_OK )
9b00: 7b 0a 20 20 20 20 20 20 52 74 72 65 65 53 65 61 {. RtreeSea
9b10: 72 63 68 50 6f 69 6e 74 20 2a 70 4e 65 77 3b 0a rchPoint *pNew;.
9b20: 20 20 20 20 20 20 70 4e 65 77 20 3d 20 72 74 72 pNew = rtr
9b30: 65 65 53 65 61 72 63 68 50 6f 69 6e 74 4e 65 77 eeSearchPointNew
9b40: 28 70 43 73 72 2c 20 52 54 52 45 45 5f 5a 45 52 (pCsr, RTREE_ZER
9b50: 4f 2c 20 28 75 38 29 28 70 52 74 72 65 65 2d 3e O, (u8)(pRtree->
9b60: 69 44 65 70 74 68 2b 31 29 29 3b 0a 20 20 20 20 iDepth+1));.
9b70: 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b if( pNew==0 ){
9b80: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 . rc = SQ
9b90: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 LITE_NOMEM;.
9ba0: 20 20 20 20 67 6f 74 6f 20 67 65 6f 70 6f 6c 79 goto geopoly
9bb0: 5f 66 69 6c 74 65 72 5f 65 6e 64 3b 0a 20 20 20 _filter_end;.
9bc0: 20 20 20 7d 0a 20 20 20 20 20 20 70 4e 65 77 2d }. pNew-
9bd0: 3e 69 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 >id = 1;. p
9be0: 4e 65 77 2d 3e 69 43 65 6c 6c 20 3d 20 30 3b 0a New->iCell = 0;.
9bf0: 20 20 20 20 20 20 70 4e 65 77 2d 3e 65 57 69 74 pNew->eWit
9c00: 68 69 6e 20 3d 20 50 41 52 54 4c 59 5f 57 49 54 hin = PARTLY_WIT
9c10: 48 49 4e 3b 0a 20 20 20 20 20 20 61 73 73 65 72 HIN;. asser
9c20: 74 28 20 70 43 73 72 2d 3e 62 50 6f 69 6e 74 3d t( pCsr->bPoint=
9c30: 3d 31 20 29 3b 0a 20 20 20 20 20 20 70 43 73 72 =1 );. pCsr
9c40: 2d 3e 61 4e 6f 64 65 5b 30 5d 20 3d 20 70 52 6f ->aNode[0] = pRo
9c50: 6f 74 3b 0a 20 20 20 20 20 20 70 52 6f 6f 74 20 ot;. pRoot
9c60: 3d 20 30 3b 0a 20 20 20 20 20 20 52 54 52 45 45 = 0;. RTREE
9c70: 5f 51 55 45 55 45 5f 54 52 41 43 45 28 70 43 73 _QUEUE_TRACE(pCs
9c80: 72 2c 20 22 50 55 53 48 2d 46 6d 3a 22 29 3b 0a r, "PUSH-Fm:");.
9c90: 20 20 20 20 20 20 72 63 20 3d 20 72 74 72 65 65 rc = rtree
9ca0: 53 74 65 70 54 6f 4c 65 61 66 28 70 43 73 72 29 StepToLeaf(pCsr)
9cb0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 67 65 6f ;. }. }..geo
9cc0: 70 6f 6c 79 5f 66 69 6c 74 65 72 5f 65 6e 64 3a poly_filter_end:
9cd0: 0a 20 20 6e 6f 64 65 52 65 6c 65 61 73 65 28 70 . nodeRelease(p
9ce0: 52 74 72 65 65 2c 20 70 52 6f 6f 74 29 3b 0a 20 Rtree, pRoot);.
9cf0: 20 72 74 72 65 65 52 65 6c 65 61 73 65 28 70 52 rtreeRelease(pR
9d00: 74 72 65 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 tree);. return
9d10: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 74 72 rc;.}../*.** Rtr
9d20: 65 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 ee virtual table
9d30: 20 6d 6f 64 75 6c 65 20 78 42 65 73 74 49 6e 64 module xBestInd
9d40: 65 78 20 6d 65 74 68 6f 64 2e 20 54 68 65 72 65 ex method. There
9d50: 20 61 72 65 20 74 68 72 65 65 0a 2a 2a 20 74 61 are three.** ta
9d60: 62 6c 65 20 73 63 61 6e 20 73 74 72 61 74 65 67 ble scan strateg
9d70: 69 65 73 20 74 6f 20 63 68 6f 6f 73 65 20 66 72 ies to choose fr
9d80: 6f 6d 20 28 69 6e 20 6f 72 64 65 72 20 66 72 6f om (in order fro
9d90: 6d 20 6d 6f 73 74 20 74 6f 20 0a 2a 2a 20 6c 65 m most to .** le
9da0: 61 73 74 20 64 65 73 69 72 61 62 6c 65 29 3a 0a ast desirable):.
9db0: 2a 2a 0a 2a 2a 20 20 20 69 64 78 4e 75 6d 20 20 **.** idxNum
9dc0: 20 20 20 69 64 78 53 74 72 20 20 20 20 20 20 20 idxStr
9dd0: 20 53 74 72 61 74 65 67 79 0a 2a 2a 20 20 20 2d Strategy.** -
9de0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
9df0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
9e00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a ---------------.
9e10: 2a 2a 20 20 20 20 20 31 20 20 20 20 20 20 20 20 ** 1
9e20: 22 72 6f 77 69 64 22 20 20 20 20 20 20 20 44 69 "rowid" Di
9e30: 72 65 63 74 20 6c 6f 6f 6b 75 70 20 62 79 20 72 rect lookup by r
9e40: 6f 77 69 64 2e 0a 2a 2a 20 20 20 20 20 32 20 20 owid..** 2
9e50: 20 20 20 20 20 20 22 72 74 72 65 65 22 20 20 20 "rtree"
9e60: 20 20 20 20 52 2d 74 72 65 65 20 6f 76 65 72 6c R-tree overl
9e70: 61 70 20 71 75 65 72 79 20 75 73 69 6e 67 20 67 ap query using g
9e80: 65 6f 70 6f 6c 79 5f 6f 76 65 72 6c 61 70 28 29 eopoly_overlap()
9e90: 0a 2a 2a 20 20 20 20 20 33 20 20 20 20 20 20 20 .** 3
9ea0: 20 22 72 74 72 65 65 22 20 20 20 20 20 20 20 52 "rtree" R
9eb0: 2d 74 72 65 65 20 77 69 74 68 69 6e 20 71 75 65 -tree within que
9ec0: 72 79 20 75 73 69 6e 67 20 67 65 6f 70 6f 6c 79 ry using geopoly
9ed0: 5f 77 69 74 68 69 6e 28 29 0a 2a 2a 20 20 20 20 _within().**
9ee0: 20 34 20 20 20 20 20 20 20 20 22 66 75 6c 6c 73 4 "fulls
9ef0: 63 61 6e 22 20 20 20 20 66 75 6c 6c 2d 74 61 62 can" full-tab
9f00: 6c 65 20 73 63 61 6e 2e 0a 2a 2a 20 20 20 2d 2d le scan..** --
9f10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
9f20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
9f30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 2a --------------.*
9f40: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 6f /.static int geo
9f50: 70 6f 6c 79 42 65 73 74 49 6e 64 65 78 28 73 71 polyBestIndex(sq
9f60: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c lite3_vtab *tab,
9f70: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 sqlite3_index_i
9f80: 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f 29 7b 0a nfo *pIdxInfo){.
9f90: 20 20 69 6e 74 20 69 69 3b 0a 20 20 69 6e 74 20 int ii;. int
9fa0: 69 52 6f 77 69 64 54 65 72 6d 20 3d 20 2d 31 3b iRowidTerm = -1;
9fb0: 0a 20 20 69 6e 74 20 69 46 75 6e 63 54 65 72 6d . int iFuncTerm
9fc0: 20 3d 20 2d 31 3b 0a 20 20 69 6e 74 20 69 64 78 = -1;. int idx
9fd0: 4e 75 6d 20 3d 20 30 3b 0a 0a 20 20 66 6f 72 28 Num = 0;.. for(
9fe0: 69 69 3d 30 3b 20 69 69 3c 70 49 64 78 49 6e 66 ii=0; ii<pIdxInf
9ff0: 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20 o->nConstraint;
a000: 69 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72 75 63 ii++){. struc
a010: 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f t sqlite3_index_
a020: 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70 20 3d 20 constraint *p =
a030: 26 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 &pIdxInfo->aCons
a040: 74 72 61 69 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 traint[ii];.
a050: 69 66 28 20 21 70 2d 3e 75 73 61 62 6c 65 20 29 if( !p->usable )
a060: 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 continue;. i
a070: 66 28 20 70 2d 3e 69 43 6f 6c 75 6d 6e 3c 30 20 f( p->iColumn<0
a080: 26 26 20 70 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 && p->op==SQLITE
a090: 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e _INDEX_CONSTRAIN
a0a0: 54 5f 45 51 20 20 29 7b 0a 20 20 20 20 20 20 69 T_EQ ){. i
a0b0: 52 6f 77 69 64 54 65 72 6d 20 3d 20 69 69 3b 0a RowidTerm = ii;.
a0c0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 break;.
a0d0: 20 7d 0a 20 20 20 20 69 66 28 20 70 2d 3e 69 43 }. if( p->iC
a0e0: 6f 6c 75 6d 6e 3d 3d 30 20 26 26 20 70 2d 3e 6f olumn==0 && p->o
a0f0: 70 3e 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f p>=SQLITE_INDEX_
a100: 43 4f 4e 53 54 52 41 49 4e 54 5f 46 55 4e 43 54 CONSTRAINT_FUNCT
a110: 49 4f 4e 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 ION ){. /*
a120: 70 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e p->op==SQLITE_IN
a130: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 46 DEX_CONSTRAINT_F
a140: 55 4e 43 54 49 4f 4e 20 66 6f 72 20 67 65 6f 70 UNCTION for geop
a150: 6f 6c 79 5f 6f 76 65 72 6c 61 70 28 29 0a 20 20 oly_overlap().
a160: 20 20 20 20 2a 2a 20 70 2d 3e 6f 70 3d 3d 28 53 ** p->op==(S
a170: 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 54 QLITE_INDEX_CONT
a180: 52 41 49 4e 54 5f 46 55 4e 43 54 49 4f 4e 2b 31 RAINT_FUNCTION+1
a190: 29 20 66 6f 72 20 67 65 6f 70 6f 6c 79 5f 77 69 ) for geopoly_wi
a1a0: 74 68 69 6e 28 29 2e 0a 20 20 20 20 20 20 2a 2a thin().. **
a1b0: 20 53 65 65 20 67 65 6f 70 6f 6c 79 46 69 6e 64 See geopolyFind
a1c0: 46 75 6e 63 74 69 6f 6e 28 29 20 2a 2f 0a 20 20 Function() */.
a1d0: 20 20 20 20 69 46 75 6e 63 54 65 72 6d 20 3d 20 iFuncTerm =
a1e0: 69 69 3b 0a 20 20 20 20 20 20 69 64 78 4e 75 6d ii;. idxNum
a1f0: 20 3d 20 70 2d 3e 6f 70 20 2d 20 53 51 4c 49 54 = p->op - SQLIT
a200: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 E_INDEX_CONSTRAI
a210: 4e 54 5f 46 55 4e 43 54 49 4f 4e 20 2b 20 32 3b NT_FUNCTION + 2;
a220: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 . }. }.. if
a230: 28 20 69 52 6f 77 69 64 54 65 72 6d 3e 3d 30 20 ( iRowidTerm>=0
a240: 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d ){. pIdxInfo-
a250: 3e 69 64 78 4e 75 6d 20 3d 20 31 3b 0a 20 20 20 >idxNum = 1;.
a260: 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 53 74 pIdxInfo->idxSt
a270: 72 20 3d 20 22 72 6f 77 69 64 22 3b 0a 20 20 20 r = "rowid";.
a280: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 pIdxInfo->aCons
a290: 74 72 61 69 6e 74 55 73 61 67 65 5b 69 52 6f 77 traintUsage[iRow
a2a0: 69 64 54 65 72 6d 5d 2e 61 72 67 76 49 6e 64 65 idTerm].argvInde
a2b0: 78 20 3d 20 31 3b 0a 20 20 20 20 70 49 64 78 49 x = 1;. pIdxI
a2c0: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 nfo->aConstraint
a2d0: 55 73 61 67 65 5b 69 52 6f 77 69 64 54 65 72 6d Usage[iRowidTerm
a2e0: 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 ].omit = 1;.
a2f0: 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 pIdxInfo->estima
a300: 74 65 64 43 6f 73 74 20 3d 20 33 30 2e 30 3b 0a tedCost = 30.0;.
a310: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 pIdxInfo->es
a320: 74 69 6d 61 74 65 64 52 6f 77 73 20 3d 20 31 3b timatedRows = 1;
a330: 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69 . pIdxInfo->i
a340: 64 78 46 6c 61 67 73 20 3d 20 53 51 4c 49 54 45 dxFlags = SQLITE
a350: 5f 49 4e 44 45 58 5f 53 43 41 4e 5f 55 4e 49 51 _INDEX_SCAN_UNIQ
a360: 55 45 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 UE;. return S
a370: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 QLITE_OK;. }.
a380: 69 66 28 20 69 46 75 6e 63 54 65 72 6d 3e 3d 30 if( iFuncTerm>=0
a390: 20 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f ){. pIdxInfo
a3a0: 2d 3e 69 64 78 4e 75 6d 20 3d 20 69 64 78 4e 75 ->idxNum = idxNu
a3b0: 6d 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d m;. pIdxInfo-
a3c0: 3e 69 64 78 53 74 72 20 3d 20 22 72 74 72 65 65 >idxStr = "rtree
a3d0: 22 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d ";. pIdxInfo-
a3e0: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 >aConstraintUsag
a3f0: 65 5b 69 46 75 6e 63 54 65 72 6d 5d 2e 61 72 67 e[iFuncTerm].arg
a400: 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20 20 vIndex = 1;.
a410: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 pIdxInfo->aConst
a420: 72 61 69 6e 74 55 73 61 67 65 5b 69 46 75 6e 63 raintUsage[iFunc
a430: 54 65 72 6d 5d 2e 6f 6d 69 74 20 3d 20 30 3b 0a Term].omit = 0;.
a440: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 pIdxInfo->es
a450: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 33 30 timatedCost = 30
a460: 30 2e 30 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 0.0;. pIdxInf
a470: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 52 6f 77 73 o->estimatedRows
a480: 20 3d 20 31 30 3b 0a 20 20 20 20 72 65 74 75 72 = 10;. retur
a490: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d n SQLITE_OK;. }
a4a0: 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 . pIdxInfo->idx
a4b0: 4e 75 6d 20 3d 20 34 3b 0a 20 20 70 49 64 78 49 Num = 4;. pIdxI
a4c0: 6e 66 6f 2d 3e 69 64 78 53 74 72 20 3d 20 22 66 nfo->idxStr = "f
a4d0: 75 6c 6c 73 63 61 6e 22 3b 0a 20 20 70 49 64 78 ullscan";. pIdx
a4e0: 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 Info->estimatedC
a4f0: 6f 73 74 20 3d 20 33 30 30 30 30 30 30 2e 30 3b ost = 3000000.0;
a500: 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 . pIdxInfo->est
a510: 69 6d 61 74 65 64 52 6f 77 73 20 3d 20 31 30 30 imatedRows = 100
a520: 30 30 30 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 000;. return SQ
a530: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 20 LITE_OK;.}.../*
a540: 0a 2a 2a 20 47 45 4f 50 4f 4c 59 20 76 69 72 74 .** GEOPOLY virt
a550: 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 ual table module
a560: 20 78 43 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64 2e xColumn method.
a570: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67 .*/.static int g
a580: 65 6f 70 6f 6c 79 43 6f 6c 75 6d 6e 28 73 71 6c eopolyColumn(sql
a590: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 ite3_vtab_cursor
a5a0: 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 33 5f 63 *cur, sqlite3_c
a5b0: 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20 69 6e 74 ontext *ctx, int
a5c0: 20 69 29 7b 0a 20 20 52 74 72 65 65 20 2a 70 52 i){. Rtree *pR
a5d0: 74 72 65 65 20 3d 20 28 52 74 72 65 65 20 2a 29 tree = (Rtree *)
a5e0: 63 75 72 2d 3e 70 56 74 61 62 3b 0a 20 20 52 74 cur->pVtab;. Rt
a5f0: 72 65 65 43 75 72 73 6f 72 20 2a 70 43 73 72 20 reeCursor *pCsr
a600: 3d 20 28 52 74 72 65 65 43 75 72 73 6f 72 20 2a = (RtreeCursor *
a610: 29 63 75 72 3b 0a 20 20 52 74 72 65 65 53 65 61 )cur;. RtreeSea
a620: 72 63 68 50 6f 69 6e 74 20 2a 70 20 3d 20 72 74 rchPoint *p = rt
a630: 72 65 65 53 65 61 72 63 68 50 6f 69 6e 74 46 69 reeSearchPointFi
a640: 72 73 74 28 70 43 73 72 29 3b 0a 20 20 69 6e 74 rst(pCsr);. int
a650: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b rc = SQLITE_OK;
a660: 0a 20 20 52 74 72 65 65 4e 6f 64 65 20 2a 70 4e . RtreeNode *pN
a670: 6f 64 65 20 3d 20 72 74 72 65 65 4e 6f 64 65 4f ode = rtreeNodeO
a680: 66 46 69 72 73 74 53 65 61 72 63 68 50 6f 69 6e fFirstSearchPoin
a690: 74 28 70 43 73 72 2c 20 26 72 63 29 3b 0a 0a 20 t(pCsr, &rc);..
a6a0: 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e if( rc ) return
a6b0: 20 72 63 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 rc;. if( p==0
a6c0: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f ) return SQLITE_
a6d0: 4f 4b 3b 0a 20 20 69 66 28 20 69 3d 3d 30 20 26 OK;. if( i==0 &
a6e0: 26 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 6e & sqlite3_vtab_n
a6f0: 6f 63 68 61 6e 67 65 28 63 74 78 29 20 29 20 72 ochange(ctx) ) r
a700: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b eturn SQLITE_OK;
a710: 0a 20 20 69 66 28 20 69 3c 3d 70 52 74 72 65 65 . if( i<=pRtree
a720: 2d 3e 6e 41 75 78 20 29 7b 0a 20 20 20 20 69 66 ->nAux ){. if
a730: 28 20 21 70 43 73 72 2d 3e 62 41 75 78 56 61 6c ( !pCsr->bAuxVal
a740: 69 64 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 id ){. if(
a750: 70 43 73 72 2d 3e 70 52 65 61 64 41 75 78 3d 3d pCsr->pReadAux==
a760: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 0 ){. rc
a770: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 = sqlite3_prepar
a780: 65 5f 76 33 28 70 52 74 72 65 65 2d 3e 64 62 2c e_v3(pRtree->db,
a790: 20 70 52 74 72 65 65 2d 3e 7a 52 65 61 64 41 75 pRtree->zReadAu
a7a0: 78 53 71 6c 2c 20 2d 31 2c 20 30 2c 0a 20 20 20 xSql, -1, 0,.
a7b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a7c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 26 70 43 &pC
a7d0: 73 72 2d 3e 70 52 65 61 64 41 75 78 2c 20 30 29 sr->pReadAux, 0)
a7e0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 ;. if( rc
a7f0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 ) return rc;.
a800: 20 20 20 20 7d 0a 20 20 20 20 20 20 73 71 6c 69 }. sqli
a810: 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 70 te3_bind_int64(p
a820: 43 73 72 2d 3e 70 52 65 61 64 41 75 78 2c 20 31 Csr->pReadAux, 1
a830: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 6e 6f 64 , . nod
a840: 65 47 65 74 52 6f 77 69 64 28 70 52 74 72 65 65 eGetRowid(pRtree
a850: 2c 20 70 4e 6f 64 65 2c 20 70 2d 3e 69 43 65 6c , pNode, p->iCel
a860: 6c 29 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 l));. rc =
a870: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 43 73 sqlite3_step(pCs
a880: 72 2d 3e 70 52 65 61 64 41 75 78 29 3b 0a 20 20 r->pReadAux);.
a890: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 if( rc==SQLI
a8a0: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 TE_ROW ){.
a8b0: 20 20 70 43 73 72 2d 3e 62 41 75 78 56 61 6c 69 pCsr->bAuxVali
a8c0: 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65 6c d = 1;. }el
a8d0: 73 65 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 se{. sqli
a8e0: 74 65 33 5f 72 65 73 65 74 28 70 43 73 72 2d 3e te3_reset(pCsr->
a8f0: 70 52 65 61 64 41 75 78 29 3b 0a 20 20 20 20 20 pReadAux);.
a900: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 if( rc==SQLIT
a910: 45 5f 44 4f 4e 45 20 29 20 72 63 20 3d 20 53 51 E_DONE ) rc = SQ
a920: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 20 LITE_OK;.
a930: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 return rc;.
a940: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 }. }. sq
a950: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76 61 6c lite3_result_val
a960: 75 65 28 63 74 78 2c 20 73 71 6c 69 74 65 33 5f ue(ctx, sqlite3_
a970: 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 43 73 column_value(pCs
a980: 72 2d 3e 70 52 65 61 64 41 75 78 2c 20 69 2b 32 r->pReadAux, i+2
a990: 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e ));. }. return
a9a0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a SQLITE_OK;.}...
a9b0: 2f 2a 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74 /*.** The xUpdat
a9c0: 65 20 6d 65 74 68 6f 64 20 66 6f 72 20 47 45 4f e method for GEO
a9d0: 50 4f 4c 59 20 6d 6f 64 75 6c 65 20 76 69 72 74 POLY module virt
a9e0: 75 61 6c 20 74 61 62 6c 65 73 2e 0a 2a 2a 0a 2a ual tables..**.*
a9f0: 2a 20 46 6f 72 20 44 45 4c 45 54 45 3a 0a 2a 2a * For DELETE:.**
aa00: 0a 2a 2a 20 20 20 20 20 61 72 67 76 5b 30 5d 20 .** argv[0]
aa10: 3d 20 74 68 65 20 72 6f 77 69 64 20 74 6f 20 62 = the rowid to b
aa20: 65 20 64 65 6c 65 74 65 64 0a 2a 2a 0a 2a 2a 20 e deleted.**.**
aa30: 46 6f 72 20 49 4e 53 45 52 54 3a 0a 2a 2a 0a 2a For INSERT:.**.*
aa40: 2a 20 20 20 20 20 61 72 67 76 5b 30 5d 20 3d 20 * argv[0] =
aa50: 53 51 4c 20 4e 55 4c 4c 0a 2a 2a 20 20 20 20 20 SQL NULL.**
aa60: 61 72 67 76 5b 31 5d 20 3d 20 72 6f 77 69 64 20 argv[1] = rowid
aa70: 74 6f 20 69 6e 73 65 72 74 2c 20 6f 72 20 61 6e to insert, or an
aa80: 20 53 51 4c 20 4e 55 4c 4c 20 74 6f 20 73 65 6c SQL NULL to sel
aa90: 65 63 74 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c ect automaticall
aaa0: 79 0a 2a 2a 20 20 20 20 20 61 72 67 76 5b 32 5d y.** argv[2]
aab0: 20 3d 20 5f 73 68 61 70 65 20 63 6f 6c 75 6d 6e = _shape column
aac0: 0a 2a 2a 20 20 20 20 20 61 72 67 76 5b 33 5d 20 .** argv[3]
aad0: 3d 20 66 69 72 73 74 20 61 70 70 6c 69 63 61 74 = first applicat
aae0: 69 6f 6e 2d 64 65 66 69 6e 65 64 20 63 6f 6c 75 ion-defined colu
aaf0: 6d 6e 2e 2e 2e 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 mn.....**.** For
ab00: 20 55 50 44 41 54 45 3a 0a 2a 2a 0a 2a 2a 20 20 UPDATE:.**.**
ab10: 20 20 20 61 72 67 76 5b 30 5d 20 3d 20 72 6f 77 argv[0] = row
ab20: 69 64 20 74 6f 20 6d 6f 64 69 66 79 2e 20 20 4e id to modify. N
ab30: 65 76 65 72 20 4e 55 4c 4c 0a 2a 2a 20 20 20 20 ever NULL.**
ab40: 20 61 72 67 76 5b 31 5d 20 3d 20 72 6f 77 69 64 argv[1] = rowid
ab50: 20 61 66 74 65 72 20 74 68 65 20 63 68 61 6e 67 after the chang
ab60: 65 2e 20 20 4e 65 76 65 72 20 4e 55 4c 4c 0a 2a e. Never NULL.*
ab70: 2a 20 20 20 20 20 61 72 67 76 5b 32 5d 20 3d 20 * argv[2] =
ab80: 6e 65 77 20 76 61 6c 75 65 20 66 6f 72 20 5f 73 new value for _s
ab90: 68 61 70 65 0a 2a 2a 20 20 20 20 20 61 72 67 76 hape.** argv
aba0: 5b 33 5d 20 3d 20 6e 65 77 20 76 61 6c 75 65 20 [3] = new value
abb0: 66 6f 72 20 66 69 72 73 74 20 61 70 70 6c 69 63 for first applic
abc0: 61 74 69 6f 6e 2d 64 65 66 69 6e 65 64 20 63 6f ation-defined co
abd0: 6c 75 6d 6e 2e 2e 2e 2e 0a 2a 2f 0a 73 74 61 74 lumn.....*/.stat
abe0: 69 63 20 69 6e 74 20 67 65 6f 70 6f 6c 79 55 70 ic int geopolyUp
abf0: 64 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f date(. sqlite3_
ac00: 76 74 61 62 20 2a 70 56 74 61 62 2c 20 0a 20 20 vtab *pVtab, .
ac10: 69 6e 74 20 6e 44 61 74 61 2c 20 0a 20 20 73 71 int nData, . sq
ac20: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 44 lite3_value **aD
ac30: 61 74 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69 ata, . sqlite_i
ac40: 6e 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a nt64 *pRowid.){.
ac50: 20 20 52 74 72 65 65 20 2a 70 52 74 72 65 65 20 Rtree *pRtree
ac60: 3d 20 28 52 74 72 65 65 20 2a 29 70 56 74 61 62 = (Rtree *)pVtab
ac70: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c ;. int rc = SQL
ac80: 49 54 45 5f 4f 4b 3b 0a 20 20 52 74 72 65 65 43 ITE_OK;. RtreeC
ac90: 65 6c 6c 20 63 65 6c 6c 3b 20 20 20 20 20 20 20 ell cell;
aca0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 /* New
acb0: 20 63 65 6c 6c 20 74 6f 20 69 6e 73 65 72 74 20 cell to insert
acc0: 69 66 20 6e 44 61 74 61 3e 31 20 2a 2f 0a 20 20 if nData>1 */.
acd0: 69 36 34 20 6f 6c 64 52 6f 77 69 64 3b 20 20 20 i64 oldRowid;
ace0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
acf0: 2f 2a 20 54 68 65 20 6f 6c 64 20 72 6f 77 69 64 /* The old rowid
ad00: 20 2a 2f 0a 20 20 69 6e 74 20 6f 6c 64 52 6f 77 */. int oldRow
ad10: 69 64 56 61 6c 69 64 3b 20 20 20 20 20 20 20 20 idValid;
ad20: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 /* True if
ad30: 20 6f 6c 64 52 6f 77 69 64 20 69 73 20 76 61 6c oldRowid is val
ad40: 69 64 20 2a 2f 0a 20 20 69 36 34 20 6e 65 77 52 id */. i64 newR
ad50: 6f 77 69 64 3b 20 20 20 20 20 20 20 20 20 20 20 owid;
ad60: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e /* The n
ad70: 65 77 20 72 6f 77 69 64 20 2a 2f 0a 20 20 69 6e ew rowid */. in
ad80: 74 20 6e 65 77 52 6f 77 69 64 56 61 6c 69 64 3b t newRowidValid;
ad90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
ada0: 20 54 72 75 65 20 69 66 20 6e 65 77 52 6f 77 69 True if newRowi
adb0: 64 20 69 73 20 76 61 6c 69 64 20 2a 2f 0a 20 20 d is valid */.
adc0: 69 6e 74 20 63 6f 6f 72 64 43 68 61 6e 67 65 20 int coordChange
add0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 = 0;
ade0: 2f 2a 20 43 68 61 6e 67 65 20 69 6e 20 63 6f 6f /* Change in coo
adf0: 72 64 69 6e 61 74 65 73 20 2a 2f 0a 0a 20 20 69 rdinates */.. i
ae00: 66 28 20 70 52 74 72 65 65 2d 3e 6e 4e 6f 64 65 f( pRtree->nNode
ae10: 52 65 66 20 29 7b 0a 20 20 20 20 2f 2a 20 55 6e Ref ){. /* Un
ae20: 61 62 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f able to write to
ae30: 20 74 68 65 20 62 74 72 65 65 20 77 68 69 6c 65 the btree while
ae40: 20 61 6e 6f 74 68 65 72 20 63 75 72 73 6f 72 20 another cursor
ae50: 69 73 20 72 65 61 64 69 6e 67 20 66 72 6f 6d 20 is reading from
ae60: 69 74 2c 0a 20 20 20 20 2a 2a 20 73 69 6e 63 65 it,. ** since
ae70: 20 74 68 65 20 77 72 69 74 65 20 6d 69 67 68 74 the write might
ae80: 20 64 6f 20 61 20 72 65 62 61 6c 61 6e 63 65 20 do a rebalance
ae90: 77 68 69 63 68 20 77 6f 75 6c 64 20 64 69 73 72 which would disr
aea0: 75 70 74 20 74 68 65 20 72 65 61 64 0a 20 20 20 upt the read.
aeb0: 20 2a 2a 20 63 75 72 73 6f 72 2e 20 2a 2f 0a 20 ** cursor. */.
aec0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 return SQLITE
aed0: 5f 4c 4f 43 4b 45 44 5f 56 54 41 42 3b 0a 20 20 _LOCKED_VTAB;.
aee0: 7d 0a 20 20 72 74 72 65 65 52 65 66 65 72 65 6e }. rtreeReferen
aef0: 63 65 28 70 52 74 72 65 65 29 3b 0a 20 20 61 73 ce(pRtree);. as
af00: 73 65 72 74 28 6e 44 61 74 61 3e 3d 31 29 3b 0a sert(nData>=1);.
af10: 0a 20 20 6f 6c 64 52 6f 77 69 64 56 61 6c 69 64 . oldRowidValid
af20: 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 = sqlite3_value
af30: 5f 74 79 70 65 28 61 44 61 74 61 5b 30 5d 29 21 _type(aData[0])!
af40: 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 3b 3b 0a 20 =SQLITE_NULL;;.
af50: 20 6f 6c 64 52 6f 77 69 64 20 3d 20 6f 6c 64 52 oldRowid = oldR
af60: 6f 77 69 64 56 61 6c 69 64 20 3f 20 73 71 6c 69 owidValid ? sqli
af70: 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 te3_value_int64(
af80: 61 44 61 74 61 5b 30 5d 29 20 3a 20 30 3b 0a 20 aData[0]) : 0;.
af90: 20 6e 65 77 52 6f 77 69 64 56 61 6c 69 64 20 3d newRowidValid =
afa0: 20 6e 44 61 74 61 3e 31 20 26 26 20 73 71 6c 69 nData>1 && sqli
afb0: 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 te3_value_type(a
afc0: 44 61 74 61 5b 31 5d 29 21 3d 53 51 4c 49 54 45 Data[1])!=SQLITE
afd0: 5f 4e 55 4c 4c 3b 0a 20 20 6e 65 77 52 6f 77 69 _NULL;. newRowi
afe0: 64 20 3d 20 6e 65 77 52 6f 77 69 64 56 61 6c 69 d = newRowidVali
aff0: 64 20 3f 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 d ? sqlite3_valu
b000: 65 5f 69 6e 74 36 34 28 61 44 61 74 61 5b 31 5d e_int64(aData[1]
b010: 29 20 3a 20 30 3b 0a 20 20 63 65 6c 6c 2e 69 52 ) : 0;. cell.iR
b020: 6f 77 69 64 20 3d 20 6e 65 77 52 6f 77 69 64 3b owid = newRowid;
b030: 0a 0a 20 20 69 66 28 20 6e 44 61 74 61 3e 31 20 .. if( nData>1
b040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
b050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
b060: 2f 2a 20 6e 6f 74 20 61 20 44 45 4c 45 54 45 20 /* not a DELETE
b070: 2a 2f 0a 20 20 20 26 26 20 28 21 6f 6c 64 52 6f */. && (!oldRo
b080: 77 69 64 56 61 6c 69 64 20 20 20 20 20 20 20 20 widValid
b090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
b0a0: 20 2f 2a 20 49 4e 53 45 52 54 20 2a 2f 0a 20 20 /* INSERT */.
b0b0: 20 20 20 20 20 20 7c 7c 20 21 73 71 6c 69 74 65 || !sqlite
b0c0: 33 5f 76 61 6c 75 65 5f 6e 6f 63 68 61 6e 67 65 3_value_nochange
b0d0: 28 61 44 61 74 61 5b 32 5d 29 20 20 2f 2a 20 55 (aData[2]) /* U
b0e0: 50 44 41 54 45 20 5f 73 68 61 70 65 20 2a 2f 0a PDATE _shape */.
b0f0: 20 20 20 20 20 20 20 20 7c 7c 20 6f 6c 64 52 6f || oldRo
b100: 77 69 64 21 3d 6e 65 77 52 6f 77 69 64 29 20 20 wid!=newRowid)
b110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
b120: 20 52 6f 77 69 64 20 63 68 61 6e 67 65 20 2a 2f Rowid change */
b130: 0a 20 20 29 7b 0a 20 20 20 20 67 65 6f 70 6f 6c . ){. geopol
b140: 79 42 42 6f 78 28 30 2c 20 61 44 61 74 61 5b 32 yBBox(0, aData[2
b150: 5d 2c 20 63 65 6c 6c 2e 61 43 6f 6f 72 64 2c 20 ], cell.aCoord,
b160: 26 72 63 29 3b 0a 20 20 20 20 69 66 28 20 72 63 &rc);. if( rc
b170: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63 ){. if( rc
b180: 3d 3d 53 51 4c 49 54 45 5f 45 52 52 4f 52 20 29 ==SQLITE_ERROR )
b190: 7b 0a 20 20 20 20 20 20 20 20 70 56 74 61 62 2d {. pVtab-
b1a0: 3e 7a 45 72 72 4d 73 67 20 3d 0a 20 20 20 20 20 >zErrMsg =.
b1b0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 sqlite3_mpr
b1c0: 69 6e 74 66 28 22 5f 73 68 61 70 65 20 64 6f 65 intf("_shape doe
b1d0: 73 20 6e 6f 74 20 63 6f 6e 74 61 69 6e 20 61 20 s not contain a
b1e0: 76 61 6c 69 64 20 70 6f 6c 79 67 6f 6e 22 29 3b valid polygon");
b1f0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 67 . }. g
b200: 6f 74 6f 20 67 65 6f 70 6f 6c 79 5f 75 70 64 61 oto geopoly_upda
b210: 74 65 5f 65 6e 64 3b 0a 20 20 20 20 7d 0a 20 20 te_end;. }.
b220: 20 20 63 6f 6f 72 64 43 68 61 6e 67 65 20 3d 20 coordChange =
b230: 31 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 61 20 1;.. /* If a
b240: 72 6f 77 69 64 20 76 61 6c 75 65 20 77 61 73 20 rowid value was
b250: 73 75 70 70 6c 69 65 64 2c 20 63 68 65 63 6b 20 supplied, check
b260: 69 66 20 69 74 20 69 73 20 61 6c 72 65 61 64 79 if it is already
b270: 20 70 72 65 73 65 6e 74 20 69 6e 20 0a 20 20 20 present in .
b280: 20 2a 2a 20 74 68 65 20 74 61 62 6c 65 2e 20 49 ** the table. I
b290: 66 20 73 6f 2c 20 74 68 65 20 63 6f 6e 73 74 72 f so, the constr
b2a0: 61 69 6e 74 20 68 61 73 20 66 61 69 6c 65 64 2e aint has failed.
b2b0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 6e 65 77 52 */. if( newR
b2c0: 6f 77 69 64 56 61 6c 69 64 20 26 26 20 28 21 6f owidValid && (!o
b2d0: 6c 64 52 6f 77 69 64 56 61 6c 69 64 20 7c 7c 20 ldRowidValid ||
b2e0: 6f 6c 64 52 6f 77 69 64 21 3d 6e 65 77 52 6f 77 oldRowid!=newRow
b2f0: 69 64 29 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 id) ){. int
b300: 20 73 74 65 70 72 63 3b 0a 20 20 20 20 20 20 73 steprc;. s
b310: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 qlite3_bind_int6
b320: 34 28 70 52 74 72 65 65 2d 3e 70 52 65 61 64 52 4(pRtree->pReadR
b330: 6f 77 69 64 2c 20 31 2c 20 63 65 6c 6c 2e 69 52 owid, 1, cell.iR
b340: 6f 77 69 64 29 3b 0a 20 20 20 20 20 20 73 74 65 owid);. ste
b350: 70 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 prc = sqlite3_st
b360: 65 70 28 70 52 74 72 65 65 2d 3e 70 52 65 61 64 ep(pRtree->pRead
b370: 52 6f 77 69 64 29 3b 0a 20 20 20 20 20 20 72 63 Rowid);. rc
b380: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 = sqlite3_reset
b390: 28 70 52 74 72 65 65 2d 3e 70 52 65 61 64 52 6f (pRtree->pReadRo
b3a0: 77 69 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20 wid);. if(
b3b0: 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 74 65 70 SQLITE_ROW==step
b3c0: 72 63 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 rc ){. if
b3d0: 28 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 6f ( sqlite3_vtab_o
b3e0: 6e 5f 63 6f 6e 66 6c 69 63 74 28 70 52 74 72 65 n_conflict(pRtre
b3f0: 65 2d 3e 64 62 29 3d 3d 53 51 4c 49 54 45 5f 52 e->db)==SQLITE_R
b400: 45 50 4c 41 43 45 20 29 7b 0a 20 20 20 20 20 20 EPLACE ){.
b410: 20 20 20 20 72 63 20 3d 20 72 74 72 65 65 44 65 rc = rtreeDe
b420: 6c 65 74 65 52 6f 77 69 64 28 70 52 74 72 65 65 leteRowid(pRtree
b430: 2c 20 63 65 6c 6c 2e 69 52 6f 77 69 64 29 3b 0a , cell.iRowid);.
b440: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 }else{.
b450: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 72 74 rc = rt
b460: 72 65 65 43 6f 6e 73 74 72 61 69 6e 74 45 72 72 reeConstraintErr
b470: 6f 72 28 70 52 74 72 65 65 2c 20 30 29 3b 0a 20 or(pRtree, 0);.
b480: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d }. }
b490: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a . }. }.. /*
b4a0: 20 49 66 20 61 44 61 74 61 5b 30 5d 20 69 73 20 If aData[0] is
b4b0: 6e 6f 74 20 61 6e 20 53 51 4c 20 4e 55 4c 4c 20 not an SQL NULL
b4c0: 76 61 6c 75 65 2c 20 69 74 20 69 73 20 74 68 65 value, it is the
b4d0: 20 72 6f 77 69 64 20 6f 66 20 61 0a 20 20 2a 2a rowid of a. **
b4e0: 20 72 65 63 6f 72 64 20 74 6f 20 64 65 6c 65 74 record to delet
b4f0: 65 20 66 72 6f 6d 20 74 68 65 20 72 2d 74 72 65 e from the r-tre
b500: 65 20 74 61 62 6c 65 2e 20 54 68 65 20 66 6f 6c e table. The fol
b510: 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 64 6f 65 lowing block doe
b520: 73 0a 20 20 2a 2a 20 6a 75 73 74 20 74 68 61 74 s. ** just that
b530: 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d .. */. if( rc=
b540: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 28 6e =SQLITE_OK && (n
b550: 44 61 74 61 3d 3d 31 20 7c 7c 20 28 63 6f 6f 72 Data==1 || (coor
b560: 64 43 68 61 6e 67 65 20 26 26 20 6f 6c 64 52 6f dChange && oldRo
b570: 77 69 64 56 61 6c 69 64 29 29 20 29 7b 0a 20 20 widValid)) ){.
b580: 20 20 72 63 20 3d 20 72 74 72 65 65 44 65 6c 65 rc = rtreeDele
b590: 74 65 52 6f 77 69 64 28 70 52 74 72 65 65 2c 20 teRowid(pRtree,
b5a0: 6f 6c 64 52 6f 77 69 64 29 3b 0a 20 20 7d 0a 0a oldRowid);. }..
b5b0: 20 20 2f 2a 20 49 66 20 74 68 65 20 61 44 61 74 /* If the aDat
b5c0: 61 5b 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 a[] array contai
b5d0: 6e 73 20 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 65 ns more than one
b5e0: 20 65 6c 65 6d 65 6e 74 2c 20 65 6c 65 6d 65 6e element, elemen
b5f0: 74 73 0a 20 20 2a 2a 20 28 61 44 61 74 61 5b 32 ts. ** (aData[2
b600: 5d 2e 2e 61 44 61 74 61 5b 61 72 67 63 2d 31 5d ]..aData[argc-1]
b610: 29 20 63 6f 6e 74 61 69 6e 20 61 20 6e 65 77 20 ) contain a new
b620: 72 65 63 6f 72 64 20 74 6f 20 69 6e 73 65 72 74 record to insert
b630: 20 69 6e 74 6f 0a 20 20 2a 2a 20 74 68 65 20 72 into. ** the r
b640: 2d 74 72 65 65 20 73 74 72 75 63 74 75 72 65 2e -tree structure.
b650: 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d . */. if( rc==
b660: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 44 61 SQLITE_OK && nDa
b670: 74 61 3e 31 20 26 26 20 63 6f 6f 72 64 43 68 61 ta>1 && coordCha
b680: 6e 67 65 20 29 7b 0a 20 20 20 20 2f 2a 20 49 6e nge ){. /* In
b690: 73 65 72 74 20 74 68 65 20 6e 65 77 20 72 65 63 sert the new rec
b6a0: 6f 72 64 20 69 6e 74 6f 20 74 68 65 20 72 2d 74 ord into the r-t
b6b0: 72 65 65 20 2a 2f 0a 20 20 20 20 52 74 72 65 65 ree */. Rtree
b6c0: 4e 6f 64 65 20 2a 70 4c 65 61 66 20 3d 20 30 3b Node *pLeaf = 0;
b6d0: 0a 20 20 20 20 69 66 28 20 21 6e 65 77 52 6f 77 . if( !newRow
b6e0: 69 64 56 61 6c 69 64 20 29 7b 0a 20 20 20 20 20 idValid ){.
b6f0: 20 72 63 20 3d 20 72 74 72 65 65 4e 65 77 52 6f rc = rtreeNewRo
b700: 77 69 64 28 70 52 74 72 65 65 2c 20 26 63 65 6c wid(pRtree, &cel
b710: 6c 2e 69 52 6f 77 69 64 29 3b 0a 20 20 20 20 7d l.iRowid);. }
b720: 0a 20 20 20 20 2a 70 52 6f 77 69 64 20 3d 20 63 . *pRowid = c
b730: 65 6c 6c 2e 69 52 6f 77 69 64 3b 0a 20 20 20 20 ell.iRowid;.
b740: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f if( rc==SQLITE_O
b750: 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 K ){. rc =
b760: 43 68 6f 6f 73 65 4c 65 61 66 28 70 52 74 72 65 ChooseLeaf(pRtre
b770: 65 2c 20 26 63 65 6c 6c 2c 20 30 2c 20 26 70 4c e, &cell, 0, &pL
b780: 65 61 66 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 eaf);. }.
b790: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f if( rc==SQLITE_O
b7a0: 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 K ){. int r
b7b0: 63 32 3b 0a 20 20 20 20 20 20 70 52 74 72 65 65 c2;. pRtree
b7c0: 2d 3e 69 52 65 69 6e 73 65 72 74 48 65 69 67 68 ->iReinsertHeigh
b7d0: 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 72 63 t = -1;. rc
b7e0: 20 3d 20 72 74 72 65 65 49 6e 73 65 72 74 43 65 = rtreeInsertCe
b7f0: 6c 6c 28 70 52 74 72 65 65 2c 20 70 4c 65 61 66 ll(pRtree, pLeaf
b800: 2c 20 26 63 65 6c 6c 2c 20 30 29 3b 0a 20 20 20 , &cell, 0);.
b810: 20 20 20 72 63 32 20 3d 20 6e 6f 64 65 52 65 6c rc2 = nodeRel
b820: 65 61 73 65 28 70 52 74 72 65 65 2c 20 70 4c 65 ease(pRtree, pLe
b830: 61 66 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 af);. if( r
b840: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a c==SQLITE_OK ){.
b850: 20 20 20 20 20 20 20 20 72 63 20 3d 20 72 63 32 rc = rc2
b860: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a ;. }. }.
b870: 20 20 7d 0a 0a 20 20 2f 2a 20 43 68 61 6e 67 65 }.. /* Change
b880: 20 74 68 65 20 64 61 74 61 20 2a 2f 0a 20 20 69 the data */. i
b890: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b f( rc==SQLITE_OK
b8a0: 20 26 26 20 6e 44 61 74 61 3e 31 20 29 7b 0a 20 && nData>1 ){.
b8b0: 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 sqlite3_stmt
b8c0: 2a 70 55 70 20 3d 20 70 52 74 72 65 65 2d 3e 70 *pUp = pRtree->p
b8d0: 57 72 69 74 65 41 75 78 3b 0a 20 20 20 20 69 6e WriteAux;. in
b8e0: 74 20 6a 6a 3b 0a 20 20 20 20 69 6e 74 20 6e 43 t jj;. int nC
b8f0: 68 61 6e 67 65 20 3d 20 30 3b 0a 20 20 20 20 73 hange = 0;. s
b900: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 qlite3_bind_int6
b910: 34 28 70 55 70 2c 20 31 2c 20 63 65 6c 6c 2e 69 4(pUp, 1, cell.i
b920: 52 6f 77 69 64 29 3b 0a 20 20 20 20 61 73 73 65 Rowid);. asse
b930: 72 74 28 20 70 52 74 72 65 65 2d 3e 6e 41 75 78 rt( pRtree->nAux
b940: 3e 3d 31 20 29 3b 0a 20 20 20 20 69 66 28 20 73 >=1 );. if( s
b950: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 6e 6f 63 qlite3_value_noc
b960: 68 61 6e 67 65 28 61 44 61 74 61 5b 32 5d 29 20 hange(aData[2])
b970: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 ){. sqlite3
b980: 5f 62 69 6e 64 5f 6e 75 6c 6c 28 70 55 70 2c 20 _bind_null(pUp,
b990: 32 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 2);. }else{.
b9a0: 20 20 20 20 20 47 65 6f 50 6f 6c 79 20 2a 70 20 GeoPoly *p
b9b0: 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 73 = 0;. if( s
b9c0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 qlite3_value_typ
b9d0: 65 28 61 44 61 74 61 5b 32 5d 29 3d 3d 53 51 4c e(aData[2])==SQL
b9e0: 49 54 45 5f 54 45 58 54 0a 20 20 20 20 20 20 20 ITE_TEXT.
b9f0: 26 26 20 28 70 20 3d 20 67 65 6f 70 6f 6c 79 46 && (p = geopolyF
ba00: 75 6e 63 50 61 72 61 6d 28 30 2c 20 61 44 61 74 uncParam(0, aDat
ba10: 61 5b 32 5d 2c 20 26 72 63 29 29 21 3d 30 0a 20 a[2], &rc))!=0.
ba20: 20 20 20 20 20 20 26 26 20 72 63 3d 3d 53 51 4c && rc==SQL
ba30: 49 54 45 5f 4f 4b 0a 20 20 20 20 20 20 29 7b 0a ITE_OK. ){.
ba40: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f sqlite3_
ba50: 62 69 6e 64 5f 62 6c 6f 62 28 70 55 70 2c 20 32 bind_blob(pUp, 2
ba60: 2c 20 70 2d 3e 68 64 72 2c 20 34 2b 38 2a 70 2d , p->hdr, 4+8*p-
ba70: 3e 6e 56 65 72 74 65 78 2c 20 53 51 4c 49 54 45 >nVertex, SQLITE
ba80: 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 _TRANSIENT);.
ba90: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
baa0: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 sqlite3_bind_v
bab0: 61 6c 75 65 28 70 55 70 2c 20 32 2c 20 61 44 61 alue(pUp, 2, aDa
bac0: 74 61 5b 32 5d 29 3b 0a 20 20 20 20 20 20 7d 0a ta[2]);. }.
bad0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 sqlite3_fr
bae0: 65 65 28 70 29 3b 0a 20 20 20 20 20 20 6e 43 68 ee(p);. nCh
baf0: 61 6e 67 65 20 3d 20 31 3b 0a 20 20 20 20 7d 0a ange = 1;. }.
bb00: 20 20 20 20 66 6f 72 28 6a 6a 3d 31 3b 20 6a 6a for(jj=1; jj
bb10: 3c 70 52 74 72 65 65 2d 3e 6e 41 75 78 3b 20 6a <pRtree->nAux; j
bb20: 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 6e 43 68 61 j++){. nCha
bb30: 6e 67 65 2b 2b 3b 0a 20 20 20 20 20 20 73 71 6c nge++;. sql
bb40: 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 ite3_bind_value(
bb50: 70 55 70 2c 20 6a 6a 2b 32 2c 20 61 44 61 74 61 pUp, jj+2, aData
bb60: 5b 6a 6a 2b 32 5d 29 3b 0a 20 20 20 20 7d 0a 20 [jj+2]);. }.
bb70: 20 20 20 69 66 28 20 6e 43 68 61 6e 67 65 20 29 if( nChange )
bb80: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f {. sqlite3_
bb90: 73 74 65 70 28 70 55 70 29 3b 0a 20 20 20 20 20 step(pUp);.
bba0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 rc = sqlite3_re
bbb0: 73 65 74 28 70 55 70 29 3b 0a 20 20 20 20 7d 0a set(pUp);. }.
bbc0: 20 20 7d 0a 0a 67 65 6f 70 6f 6c 79 5f 75 70 64 }..geopoly_upd
bbd0: 61 74 65 5f 65 6e 64 3a 0a 20 20 72 74 72 65 65 ate_end:. rtree
bbe0: 52 65 6c 65 61 73 65 28 70 52 74 72 65 65 29 3b Release(pRtree);
bbf0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a . return rc;.}.
bc00: 0a 2f 2a 0a 2a 2a 20 52 65 70 6f 72 74 20 74 68 ./*.** Report th
bc10: 61 74 20 67 65 6f 70 6f 6c 79 5f 6f 76 65 72 6c at geopoly_overl
bc20: 61 70 28 29 20 69 73 20 61 6e 20 6f 76 65 72 6c ap() is an overl
bc30: 6f 61 64 65 64 20 66 75 6e 63 74 69 6f 6e 20 73 oaded function s
bc40: 75 69 74 61 62 6c 65 0a 2a 2a 20 66 6f 72 20 75 uitable.** for u
bc50: 73 65 20 69 6e 20 78 42 65 73 74 49 6e 64 65 78 se in xBestIndex
bc60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ..*/.static int
bc70: 67 65 6f 70 6f 6c 79 46 69 6e 64 46 75 6e 63 74 geopolyFindFunct
bc80: 69 6f 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 ion(. sqlite3_v
bc90: 74 61 62 20 2a 70 56 74 61 62 2c 0a 20 20 69 6e tab *pVtab,. in
bca0: 74 20 6e 41 72 67 2c 0a 20 20 63 6f 6e 73 74 20 t nArg,. const
bcb0: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 76 char *zName,. v
bcc0: 6f 69 64 20 28 2a 2a 70 78 46 75 6e 63 29 28 73 oid (**pxFunc)(s
bcd0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a 2c qlite3_context*,
bce0: 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c 75 int,sqlite3_valu
bcf0: 65 2a 2a 29 2c 0a 20 20 76 6f 69 64 20 2a 2a 70 e**),. void **p
bd00: 70 41 72 67 0a 29 7b 0a 20 20 69 66 28 20 73 71 pArg.){. if( sq
bd10: 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 7a 4e lite3_stricmp(zN
bd20: 61 6d 65 2c 20 22 67 65 6f 70 6f 6c 79 5f 6f 76 ame, "geopoly_ov
bd30: 65 72 6c 61 70 22 29 3d 3d 30 20 29 7b 0a 20 20 erlap")==0 ){.
bd40: 20 20 2a 70 78 46 75 6e 63 20 3d 20 67 65 6f 70 *pxFunc = geop
bd50: 6f 6c 79 4f 76 65 72 6c 61 70 46 75 6e 63 3b 0a olyOverlapFunc;.
bd60: 20 20 20 20 2a 70 70 41 72 67 20 3d 20 30 3b 0a *ppArg = 0;.
bd70: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 return SQLIT
bd80: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 E_INDEX_CONSTRAI
bd90: 4e 54 5f 46 55 4e 43 54 49 4f 4e 3b 0a 20 20 7d NT_FUNCTION;. }
bda0: 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73 . if( sqlite3_s
bdb0: 74 72 69 63 6d 70 28 7a 4e 61 6d 65 2c 20 22 67 tricmp(zName, "g
bdc0: 65 6f 70 6f 6c 79 5f 77 69 74 68 69 6e 22 29 3d eopoly_within")=
bdd0: 3d 30 20 29 7b 0a 20 20 20 20 2a 70 78 46 75 6e =0 ){. *pxFun
bde0: 63 20 3d 20 67 65 6f 70 6f 6c 79 57 69 74 68 69 c = geopolyWithi
bdf0: 6e 46 75 6e 63 3b 0a 20 20 20 20 2a 70 70 41 72 nFunc;. *ppAr
be00: 67 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72 g = 0;. retur
be10: 6e 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 n SQLITE_INDEX_C
be20: 4f 4e 53 54 52 41 49 4e 54 5f 46 55 4e 43 54 49 ONSTRAINT_FUNCTI
be30: 4f 4e 2b 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 ON+1;. }. retu
be40: 72 6e 20 30 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 rn 0;.}...static
be50: 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 sqlite3_module
be60: 67 65 6f 70 6f 6c 79 4d 6f 64 75 6c 65 20 3d 20 geopolyModule =
be70: 7b 0a 20 20 33 2c 20 20 20 20 20 20 20 20 20 20 {. 3,
be80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
be90: 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 /* iVersion */.
bea0: 20 67 65 6f 70 6f 6c 79 43 72 65 61 74 65 2c 20 geopolyCreate,
beb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
bec0: 78 43 72 65 61 74 65 20 2d 20 63 72 65 61 74 65 xCreate - create
bed0: 20 61 20 74 61 62 6c 65 20 2a 2f 0a 20 20 67 65 a table */. ge
bee0: 6f 70 6f 6c 79 43 6f 6e 6e 65 63 74 2c 20 20 20 opolyConnect,
bef0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f /* xCo
bf00: 6e 6e 65 63 74 20 2d 20 63 6f 6e 6e 65 63 74 20 nnect - connect
bf10: 74 6f 20 61 6e 20 65 78 69 73 74 69 6e 67 20 74 to an existing t
bf20: 61 62 6c 65 20 2a 2f 0a 20 20 67 65 6f 70 6f 6c able */. geopol
bf30: 79 42 65 73 74 49 6e 64 65 78 2c 20 20 20 20 20 yBestIndex,
bf40: 20 20 20 20 20 20 2f 2a 20 78 42 65 73 74 49 6e /* xBestIn
bf50: 64 65 78 20 2d 20 44 65 74 65 72 6d 69 6e 65 20 dex - Determine
bf60: 73 65 61 72 63 68 20 73 74 72 61 74 65 67 79 20 search strategy
bf70: 2a 2f 0a 20 20 72 74 72 65 65 44 69 73 63 6f 6e */. rtreeDiscon
bf80: 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20 20 nect,
bf90: 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74 20 /* xDisconnect
bfa0: 2d 20 44 69 73 63 6f 6e 6e 65 63 74 20 66 72 6f - Disconnect fro
bfb0: 6d 20 61 20 74 61 62 6c 65 20 2a 2f 0a 20 20 72 m a table */. r
bfc0: 74 72 65 65 44 65 73 74 72 6f 79 2c 20 20 20 20 treeDestroy,
bfd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 /* xD
bfe0: 65 73 74 72 6f 79 20 2d 20 44 72 6f 70 20 61 20 estroy - Drop a
bff0: 74 61 62 6c 65 20 2a 2f 0a 20 20 72 74 72 65 65 table */. rtree
c000: 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 Open,
c010: 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 /* xOpen
c020: 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20 - open a cursor
c030: 2a 2f 0a 20 20 72 74 72 65 65 43 6c 6f 73 65 2c */. rtreeClose,
c040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
c050: 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f /* xClose - clo
c060: 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 se a cursor */.
c070: 20 67 65 6f 70 6f 6c 79 46 69 6c 74 65 72 2c 20 geopolyFilter,
c080: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
c090: 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 xFilter - config
c0a0: 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 ure scan constra
c0b0: 69 6e 74 73 20 2a 2f 0a 20 20 72 74 72 65 65 4e ints */. rtreeN
c0c0: 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 ext,
c0d0: 20 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d /* xNext -
c0e0: 20 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f advance a curso
c0f0: 72 20 2a 2f 0a 20 20 72 74 72 65 65 45 6f 66 2c r */. rtreeEof,
c100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
c110: 20 20 20 2f 2a 20 78 45 6f 66 20 2a 2f 0a 20 20 /* xEof */.
c120: 67 65 6f 70 6f 6c 79 43 6f 6c 75 6d 6e 2c 20 20 geopolyColumn,
c130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 /* x
c140: 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 Column - read da
c150: 74 61 20 2a 2f 0a 20 20 72 74 72 65 65 52 6f 77 ta */. rtreeRow
c160: 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 id,
c170: 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d 20 /* xRowid -
c180: 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 67 read data */. g
c190: 65 6f 70 6f 6c 79 55 70 64 61 74 65 2c 20 20 20 eopolyUpdate,
c1a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 /* xU
c1b0: 70 64 61 74 65 20 2d 20 77 72 69 74 65 20 64 61 pdate - write da
c1c0: 74 61 20 2a 2f 0a 20 20 72 74 72 65 65 42 65 67 ta */. rtreeBeg
c1d0: 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 2c 20 20 inTransaction,
c1e0: 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2d 20 /* xBegin -
c1f0: 62 65 67 69 6e 20 74 72 61 6e 73 61 63 74 69 6f begin transactio
c200: 6e 20 2a 2f 0a 20 20 72 74 72 65 65 45 6e 64 54 n */. rtreeEndT
c210: 72 61 6e 73 61 63 74 69 6f 6e 2c 20 20 20 20 20 ransaction,
c220: 20 20 20 2f 2a 20 78 53 79 6e 63 20 2d 20 73 79 /* xSync - sy
c230: 6e 63 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a nc transaction *
c240: 2f 0a 20 20 72 74 72 65 65 45 6e 64 54 72 61 6e /. rtreeEndTran
c250: 73 61 63 74 69 6f 6e 2c 20 20 20 20 20 20 20 20 saction,
c260: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d 20 63 6f 6d /* xCommit - com
c270: 6d 69 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 mit transaction
c280: 2a 2f 0a 20 20 72 74 72 65 65 45 6e 64 54 72 61 */. rtreeEndTra
c290: 6e 73 61 63 74 69 6f 6e 2c 20 20 20 20 20 20 20 nsaction,
c2a0: 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2d 20 /* xRollback -
c2b0: 72 6f 6c 6c 62 61 63 6b 20 74 72 61 6e 73 61 63 rollback transac
c2c0: 74 69 6f 6e 20 2a 2f 0a 20 20 67 65 6f 70 6f 6c tion */. geopol
c2d0: 79 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20 20 yFindFunction,
c2e0: 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 46 75 /* xFindFu
c2f0: 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63 74 69 6f nction - functio
c300: 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67 20 2a 2f n overloading */
c310: 0a 20 20 72 74 72 65 65 52 65 6e 61 6d 65 2c 20 . rtreeRename,
c320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
c330: 2a 20 78 52 65 6e 61 6d 65 20 2d 20 72 65 6e 61 * xRename - rena
c340: 6d 65 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a me the table */.
c350: 20 20 72 74 72 65 65 53 61 76 65 70 6f 69 6e 74 rtreeSavepoint
c360: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a , /*
c370: 20 78 53 61 76 65 70 6f 69 6e 74 20 2a 2f 0a 20 xSavepoint */.
c380: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 0,
c390: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
c3a0: 78 52 65 6c 65 61 73 65 20 2a 2f 0a 20 20 30 2c xRelease */. 0,
c3b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
c3c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f /* xRo
c3d0: 6c 6c 62 61 63 6b 54 6f 20 2a 2f 0a 20 20 72 74 llbackTo */. rt
c3e0: 72 65 65 53 68 61 64 6f 77 4e 61 6d 65 20 20 20 reeShadowName
c3f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 /* xSh
c400: 61 64 6f 77 4e 61 6d 65 20 2a 2f 0a 7d 3b 0a 0a adowName */.};..
c410: 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c 69 74 static int sqlit
c420: 65 33 5f 67 65 6f 70 6f 6c 79 5f 69 6e 69 74 28 e3_geopoly_init(
c430: 73 71 6c 69 74 65 33 20 2a 64 62 29 7b 0a 20 20 sqlite3 *db){.
c440: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f int rc = SQLITE_
c450: 4f 4b 3b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e OK;. static con
c460: 73 74 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20 st struct {.
c470: 76 6f 69 64 20 28 2a 78 46 75 6e 63 29 28 73 71 void (*xFunc)(sq
c480: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 lite3_context*,i
c490: 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 nt,sqlite3_value
c4a0: 2a 2a 29 3b 0a 20 20 20 20 73 69 67 6e 65 64 20 **);. signed
c4b0: 63 68 61 72 20 6e 41 72 67 3b 0a 20 20 20 20 75 char nArg;. u
c4c0: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 62 50 75 nsigned char bPu
c4d0: 72 65 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 re;. const ch
c4e0: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 7d 20 61 ar *zName;. } a
c4f0: 46 75 6e 63 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 Func[] = {.
c500: 7b 20 67 65 6f 70 6f 6c 79 41 72 65 61 46 75 6e { geopolyAreaFun
c510: 63 2c 20 20 20 20 20 20 20 20 20 20 31 2c 20 31 c, 1, 1
c520: 2c 20 20 20 20 22 67 65 6f 70 6f 6c 79 5f 61 72 , "geopoly_ar
c530: 65 61 22 20 20 20 20 20 20 20 20 20 20 20 20 20 ea"
c540: 7d 2c 0a 20 20 20 20 20 7b 20 67 65 6f 70 6f 6c },. { geopol
c550: 79 42 6c 6f 62 46 75 6e 63 2c 20 20 20 20 20 20 yBlobFunc,
c560: 20 20 20 20 31 2c 20 31 2c 20 20 20 20 22 67 65 1, 1, "ge
c570: 6f 70 6f 6c 79 5f 62 6c 6f 62 22 20 20 20 20 20 opoly_blob"
c580: 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 },.
c590: 7b 20 67 65 6f 70 6f 6c 79 4a 73 6f 6e 46 75 6e { geopolyJsonFun
c5a0: 63 2c 20 20 20 20 20 20 20 20 20 20 31 2c 20 31 c, 1, 1
c5b0: 2c 20 20 20 20 22 67 65 6f 70 6f 6c 79 5f 6a 73 , "geopoly_js
c5c0: 6f 6e 22 20 20 20 20 20 20 20 20 20 20 20 20 20 on"
c5d0: 7d 2c 0a 20 20 20 20 20 7b 20 67 65 6f 70 6f 6c },. { geopol
c5e0: 79 53 76 67 46 75 6e 63 2c 20 20 20 20 20 20 20 ySvgFunc,
c5f0: 20 20 20 2d 31 2c 20 31 2c 20 20 20 20 22 67 65 -1, 1, "ge
c600: 6f 70 6f 6c 79 5f 73 76 67 22 20 20 20 20 20 20 opoly_svg"
c610: 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 },.
c620: 7b 20 67 65 6f 70 6f 6c 79 57 69 74 68 69 6e 46 { geopolyWithinF
c630: 75 6e 63 2c 20 20 20 20 20 20 20 20 32 2c 20 31 unc, 2, 1
c640: 2c 20 20 20 20 22 67 65 6f 70 6f 6c 79 5f 77 69 , "geopoly_wi
c650: 74 68 69 6e 22 20 20 20 20 20 20 20 20 20 20 20 thin"
c660: 7d 2c 0a 20 20 20 20 20 7b 20 67 65 6f 70 6f 6c },. { geopol
c670: 79 43 6f 6e 74 61 69 6e 73 50 6f 69 6e 74 46 75 yContainsPointFu
c680: 6e 63 2c 20 33 2c 20 31 2c 20 20 20 20 22 67 65 nc, 3, 1, "ge
c690: 6f 70 6f 6c 79 5f 63 6f 6e 74 61 69 6e 73 5f 70 opoly_contains_p
c6a0: 6f 69 6e 74 22 20 20 20 7d 2c 0a 20 20 20 20 20 oint" },.
c6b0: 7b 20 67 65 6f 70 6f 6c 79 4f 76 65 72 6c 61 70 { geopolyOverlap
c6c0: 46 75 6e 63 2c 20 20 20 20 20 20 20 32 2c 20 31 Func, 2, 1
c6d0: 2c 20 20 20 20 22 67 65 6f 70 6f 6c 79 5f 6f 76 , "geopoly_ov
c6e0: 65 72 6c 61 70 22 20 20 20 20 20 20 20 20 20 20 erlap"
c6f0: 7d 2c 0a 20 20 20 20 20 7b 20 67 65 6f 70 6f 6c },. { geopol
c700: 79 44 65 62 75 67 46 75 6e 63 2c 20 20 20 20 20 yDebugFunc,
c710: 20 20 20 20 31 2c 20 30 2c 20 20 20 20 22 67 65 1, 0, "ge
c720: 6f 70 6f 6c 79 5f 64 65 62 75 67 22 20 20 20 20 opoly_debug"
c730: 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 },.
c740: 7b 20 67 65 6f 70 6f 6c 79 42 42 6f 78 46 75 6e { geopolyBBoxFun
c750: 63 2c 20 20 20 20 20 20 20 20 20 20 31 2c 20 31 c, 1, 1
c760: 2c 20 20 20 20 22 67 65 6f 70 6f 6c 79 5f 62 62 , "geopoly_bb
c770: 6f 78 22 20 20 20 20 20 20 20 20 20 20 20 20 20 ox"
c780: 7d 2c 0a 20 20 20 20 20 7b 20 67 65 6f 70 6f 6c },. { geopol
c790: 79 58 66 6f 72 6d 46 75 6e 63 2c 20 20 20 20 20 yXformFunc,
c7a0: 20 20 20 20 37 2c 20 31 2c 20 20 20 20 22 67 65 7, 1, "ge
c7b0: 6f 70 6f 6c 79 5f 78 66 6f 72 6d 22 20 20 20 20 opoly_xform"
c7c0: 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 },.
c7d0: 7b 20 67 65 6f 70 6f 6c 79 52 65 67 75 6c 61 72 { geopolyRegular
c7e0: 46 75 6e 63 2c 20 20 20 20 20 20 20 34 2c 20 31 Func, 4, 1
c7f0: 2c 20 20 20 20 22 67 65 6f 70 6f 6c 79 5f 72 65 , "geopoly_re
c800: 67 75 6c 61 72 22 20 20 20 20 20 20 20 20 20 20 gular"
c810: 7d 2c 0a 20 20 20 20 20 7b 20 67 65 6f 70 6f 6c },. { geopol
c820: 79 43 63 77 46 75 6e 63 2c 20 20 20 20 20 20 20 yCcwFunc,
c830: 20 20 20 20 31 2c 20 31 2c 20 20 20 20 22 67 65 1, 1, "ge
c840: 6f 70 6f 6c 79 5f 63 63 77 22 20 20 20 20 20 20 opoly_ccw"
c850: 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 7d 3b 0a },. };.
c860: 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73 static const s
c870: 74 72 75 63 74 20 7b 0a 20 20 20 20 76 6f 69 64 truct {. void
c880: 20 28 2a 78 53 74 65 70 29 28 73 71 6c 69 74 65 (*xStep)(sqlite
c890: 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c 73 3_context*,int,s
c8a0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 3b qlite3_value**);
c8b0: 0a 20 20 20 20 76 6f 69 64 20 28 2a 78 46 69 6e . void (*xFin
c8c0: 61 6c 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 al)(sqlite3_cont
c8d0: 65 78 74 2a 29 3b 0a 20 20 20 20 63 6f 6e 73 74 ext*);. const
c8e0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 char *zName;.
c8f0: 7d 20 61 41 67 67 5b 5d 20 3d 20 7b 0a 20 20 20 } aAgg[] = {.
c900: 20 20 7b 20 67 65 6f 70 6f 6c 79 42 42 6f 78 53 { geopolyBBoxS
c910: 74 65 70 2c 20 67 65 6f 70 6f 6c 79 42 42 6f 78 tep, geopolyBBox
c920: 46 69 6e 61 6c 2c 20 22 67 65 6f 70 6f 6c 79 5f Final, "geopoly_
c930: 67 72 6f 75 70 5f 62 62 6f 78 22 20 20 20 20 7d group_bbox" }
c940: 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a ,. };. int i;.
c950: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a for(i=0; i<siz
c960: 65 6f 66 28 61 46 75 6e 63 29 2f 73 69 7a 65 6f eof(aFunc)/sizeo
c970: 66 28 61 46 75 6e 63 5b 30 5d 29 20 26 26 20 72 f(aFunc[0]) && r
c980: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b c==SQLITE_OK; i+
c990: 2b 29 7b 0a 20 20 20 20 69 6e 74 20 65 6e 63 20 +){. int enc
c9a0: 3d 20 61 46 75 6e 63 5b 69 5d 2e 62 50 75 72 65 = aFunc[i].bPure
c9b0: 20 3f 20 53 51 4c 49 54 45 5f 55 54 46 38 7c 53 ? SQLITE_UTF8|S
c9c0: 51 4c 49 54 45 5f 44 45 54 45 52 4d 49 4e 49 53 QLITE_DETERMINIS
c9d0: 54 49 43 20 3a 20 53 51 4c 49 54 45 5f 55 54 46 TIC : SQLITE_UTF
c9e0: 38 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 8;. rc = sqli
c9f0: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 te3_create_funct
ca00: 69 6f 6e 28 64 62 2c 20 61 46 75 6e 63 5b 69 5d ion(db, aFunc[i]
ca10: 2e 7a 4e 61 6d 65 2c 20 61 46 75 6e 63 5b 69 5d .zName, aFunc[i]
ca20: 2e 6e 41 72 67 2c 0a 20 20 20 20 20 20 20 20 20 .nArg,.
ca30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
ca40: 20 20 20 20 20 20 20 20 65 6e 63 2c 20 30 2c 0a enc, 0,.
ca50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
ca60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
ca70: 20 61 46 75 6e 63 5b 69 5d 2e 78 46 75 6e 63 2c aFunc[i].xFunc,
ca80: 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 66 6f 0, 0);. }. fo
ca90: 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 r(i=0; i<sizeof(
caa0: 61 41 67 67 29 2f 73 69 7a 65 6f 66 28 61 41 67 aAgg)/sizeof(aAg
cab0: 67 5b 30 5d 29 20 26 26 20 72 63 3d 3d 53 51 4c g[0]) && rc==SQL
cac0: 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 ITE_OK; i++){.
cad0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 rc = sqlite3_c
cae0: 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 reate_function(d
caf0: 62 2c 20 61 41 67 67 5b 69 5d 2e 7a 4e 61 6d 65 b, aAgg[i].zName
cb00: 2c 20 31 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 , 1, SQLITE_UTF8
cb10: 2c 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 , 0,.
cb20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
cb30: 20 20 20 20 20 20 30 2c 20 61 41 67 67 5b 69 5d 0, aAgg[i]
cb40: 2e 78 53 74 65 70 2c 20 61 41 67 67 5b 69 5d 2e .xStep, aAgg[i].
cb50: 78 46 69 6e 61 6c 29 3b 0a 20 20 7d 0a 20 20 69 xFinal);. }. i
cb60: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b f( rc==SQLITE_OK
cb70: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c ){. rc = sql
cb80: 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 ite3_create_modu
cb90: 6c 65 5f 76 32 28 64 62 2c 20 22 67 65 6f 70 6f le_v2(db, "geopo
cba0: 6c 79 22 2c 20 26 67 65 6f 70 6f 6c 79 4d 6f 64 ly", &geopolyMod
cbb0: 75 6c 65 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a ule, 0, 0);. }.
cbc0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a return rc;.}.