/ Hex Artifact Content
Login

Artifact 061432bddc38c4c10c7e4ce940d581c886d65bb5814b4b65b46ad046aa85eaa2:


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  &ii;.      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;.}.