From a8c0beff470c52cd4537e13602dc87c6e52cdb2e Mon Sep 17 00:00:00 2001 From: Karim Bahgat Date: Wed, 3 Jun 2015 10:37:51 +0200 Subject: [PATCH] Renamed from PyQuadTree to Pyqtree --- README.rst | 16 +- build/doc/index.html | 522 ------------------------------------------ dist/Pyqtree-0.22.zip | Bin 0 -> 8848 bytes dist/Pyqtree-0.23.zip | Bin 0 -> 8819 bytes pyqtree.py | 14 +- pyqtree.pyc | Bin 10364 -> 10278 bytes setup.py | 8 +- upload.py | 7 +- 8 files changed, 22 insertions(+), 545 deletions(-) create mode 100644 dist/Pyqtree-0.22.zip create mode 100644 dist/Pyqtree-0.23.zip diff --git a/README.rst b/README.rst index 114d0e5..5e95e5c 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ -PyQuadTree -========== +Pyqtree +======= -PyQuadTree is a pure Python spatial index for GIS or rendering usage. It +Pyqtree is a pure Python spatial index for GIS or rendering usage. It stores and quickly retrieves items from a 2x2 rectangular grid area, and grows in depth and detail as more items are added. The actual quad tree implementation is adapted from `Matt Rasmussen's compbio @@ -16,13 +16,13 @@ Python 2 and 3. Dependencies ------------ -PyQuadTree is written in pure Python and has no dependencies. +Pyqtree is written in pure Python and has no dependencies. Installing It ------------- -Installing PyQuadTree can be done by opening your terminal or -commandline and typing: +Installing Pyqtree can be done by opening your terminal or commandline +and typing: :: @@ -73,8 +73,8 @@ main usage! More Information: ----------------- -- `Home Page `__ -- `API Documentation `__ +- `Home Page `__ +- `API Documentation `__ License: -------- diff --git a/build/doc/index.html b/build/doc/index.html index 78662dd..ac29065 100644 --- a/build/doc/index.html +++ b/build/doc/index.html @@ -1034,13 +1034,6 @@
- -
-
class Index(_QuadTree):
-    """
-    The top spatial index to be created by the user. Once created it can be
-    populated with geographically placed members that can later be tested for
-    intersection with a user inputted geographic bounding box. Note that the
-    index can be iterated through in a for-statement, which loops through all
-    all the quad instances and lets you access their properties.
-    """
-    def __init__(self, bbox, maxitems=10, maxdepth=20):
-        """
-        Parameters:
-
-        - **bbox**: The coordinate system bounding box of the area that the quadtree should
-            keep track of, as a 4-length sequence (xmin,ymin,xmax,ymax)
-        - **maxmembers** (optional): The maximum number of items allowed per quad before splitting
-            up into four new subquads. Default is 10. 
-        - **maxdepth** (optional): The maximum levels of nested subquads, after which no more splitting
-            occurs and the bottommost quad nodes may grow indefinately. Default is 20. 
-        """
-        x1,y1,x2,y2 = bbox
-        width,height = x2-x1,y2-y1
-        midx,midy = x1+width/2.0, y1+height/2.0
-        self.nodes = []
-        self.children = []
-        self.center = [midx, midy]
-        self.width,self.height = width,height
-        self.depth = 0
-        self.maxitems = maxitems
-        self.maxdepth = maxdepth
-
-    def insert(self, item, bbox):
-        """
-        Inserts an item into the quadtree along with its bounding box.
-
-        Parameters:
-
-        - **item**: The item to insert into the index, which will be returned by the intersection method
-        - **bbox**: The spatial bounding box tuple of the item, with four members (xmin,ymin,xmax,ymax)
-        """
-        self._insert(item, bbox)
-
-    def intersect(self, bbox):
-        """
-        Intersects an input boundingbox rectangle with all of the items
-        contained in the quadtree. 
-
-        Parameters:
-
-        - **bbox**: A spatial bounding box tuple with four members (xmin,ymin,xmax,ymax)
-
-        Returns:
-
-        - A list of inserted items whose bounding boxes intersect with the input rectangle.
-        """
-        self._intersect(bbox)
-    
-    def countmembers(self):
-        """
-        Returns:
-        
-        - A count of the total number of members/items/nodes inserted into
-            this quadtree and all of its child trees.
-        """
-        size = 0
-        for child in self.children:
-            size += child.countmembers()
-        size += len(self.nodes)
-        return size
-
- -
@@ -1485,67 +1094,6 @@

Ancestors (in MRO)

  • Index
  • pyqtree._QuadTree
  • -

    Instance variables

    -
    -

    var center

    - - - - -
    -
    - -
    -
    -

    var children

    - - - - -
    -
    - -
    -
    -

    var depth

    - - - - -
    -
    - -
    -
    -

    var maxdepth

    - - - - -
    -
    - -
    -
    -

    var maxitems

    - - - - -
    -
    - -
    -
    -

    var nodes

    - - - - -
    -
    - -

    Methods

    @@ -1566,31 +1114,6 @@

    Methods

    occurs and the bottommost quad nodes may grow indefinately. Default is 20.
    - -
    -
    def __init__(self, bbox, maxitems=10, maxdepth=20):
    -    """
    -    Parameters:
    -    - **bbox**: The coordinate system bounding box of the area that the quadtree should
    -        keep track of, as a 4-length sequence (xmin,ymin,xmax,ymax)
    -    - **maxmembers** (optional): The maximum number of items allowed per quad before splitting
    -        up into four new subquads. Default is 10. 
    -    - **maxdepth** (optional): The maximum levels of nested subquads, after which no more splitting
    -        occurs and the bottommost quad nodes may grow indefinately. Default is 20. 
    -    """
    -    x1,y1,x2,y2 = bbox
    -    width,height = x2-x1,y2-y1
    -    midx,midy = x1+width/2.0, y1+height/2.0
    -    self.nodes = []
    -    self.children = []
    -    self.center = [midx, midy]
    -    self.width,self.height = width,height
    -    self.depth = 0
    -    self.maxitems = maxitems
    -    self.maxdepth = maxdepth
    -
    - -
    @@ -1610,23 +1133,6 @@

    Methods

    this quadtree and all of its child trees.
    - -
    -
    def countmembers(self):
    -    """
    -    Returns:
    -    
    -    - A count of the total number of members/items/nodes inserted into
    -        this quadtree and all of its child trees.
    -    """
    -    size = 0
    -    for child in self.children:
    -        size += child.countmembers()
    -    size += len(self.nodes)
    -    return size
    -
    - -
    @@ -1647,19 +1153,6 @@

    Methods

  • bbox: The spatial bounding box tuple of the item, with four members (xmin,ymin,xmax,ymax)
  • - -
    -
    def insert(self, item, bbox):
    -    """
    -    Inserts an item into the quadtree along with its bounding box.
    -    Parameters:
    -    - **item**: The item to insert into the index, which will be returned by the intersection method
    -    - **bbox**: The spatial bounding box tuple of the item, with four members (xmin,ymin,xmax,ymax)
    -    """
    -    self._insert(item, bbox)
    -
    - -
    @@ -1684,21 +1177,6 @@

    Methods

  • A list of inserted items whose bounding boxes intersect with the input rectangle.
  • - -
    -
    def intersect(self, bbox):
    -    """
    -    Intersects an input boundingbox rectangle with all of the items
    -    contained in the quadtree. 
    -    Parameters:
    -    - **bbox**: A spatial bounding box tuple with four members (xmin,ymin,xmax,ymax)
    -    Returns:
    -    - A list of inserted items whose bounding boxes intersect with the input rectangle.
    -    """
    -    self._intersect(bbox)
    -
    - -
    diff --git a/dist/Pyqtree-0.22.zip b/dist/Pyqtree-0.22.zip new file mode 100644 index 0000000000000000000000000000000000000000..f626d666a86a3a404ca17616d688484e898c28f5 GIT binary patch literal 8848 zcmeI2Wl$XJ*6#=1Sa4^M;5s+~f)4Jk!QCbh+$A^!w*W)%;1Jy1Ex{qUyE_EJP2O|f zlYLVA-u?A{*xl9DRbAD;T2;^L_59cRx3U}@JT3qLKmvrTbW678>-T#h007I+006un zPnA91I6In~v#^0UI9QeCq*!DWC6$u2PV5(WFdtucJaw0S8^b+~p?(!AsvVNA@QKKJ zqEx0HqkC)uo8?WMbW)zlLHo)}*@#VzJ=N!LaKmqo&z6_Yyct@hg9t8!^IV2@!=mw} zCI^$~&BSM~=G&CtcNi}bxWL)U~5!&;#)*v^|Ak^&hu(xYDm3mgD^*P^ZwzSY*X0)hOPN9QXwdyAaQ=Ka{@-bev zl>7Dbybh$ZsYnPd@taw>!p{SSx5f(aVb+`r=3Mm2itNF&Yn6;NWu^Gkxn1-!$&rCt5Y_LTQ#5Pi%kA21WG zCwgsa81NYQNid6XNDp7ttJ4^jL`i(le1h$pJ3~u>TNhrEld7;=P(zBXxo41G8B2Va zugTY?wqpsCz`d$k-EyaD1N<%z>y#rV+FmHW`Qt@D2DzuvGIY@c-2of?L3VOaneTHW z)-$KI${L5qTo1P>Te3|-^v`W1!2$_1YGal0riC%E7zx(4N&S-A4aS<4lW1Mm-JU}3 zMER8ypCbi!9U?+avaMMd*mWnGXyJBRa(I$xtkmeEC`cB%MLJ-e1E}C2 zhAC`eeFBoXN_UJJ;h6A3>aLL0i~IsUdMhL!)(g+RJXpj2M%};*&7BY&qVUJkV9|4d z+^8WEM|04+akQ5}S$*mu)fabv&Y6v)cY1i1dZK7wH3U$QADP?4G%%c3-UF|MipTC0 z9oWacUc(z^k3|t=VS!gJSvB*X_ouNHbWv*veK?DeYF=6)fc2sB(Lnse>k%SZ)MPme zhsg7}GS89gT+&c(N(GGA07E2^qd zwlzJCRU~8I)P@v!Nj?k)-RsUrex&VA4}FhDjDe%Xlq!x+>UlrmuoGB3rZVAGbGiq1 z)PXhEPPg1~2}-N^^M3!lBnEO0c{M86i96-;=OaVrz->_9vl7vzGizLNYY~e}B?KoZ zT&wRF{lEin$eQUR3tMij?4$;Nmczk_!!KA0*8O|yrXsaHPj{b*fst~Kout0^V z7pMKx+&2^3IcT04W1YjfM83WcFv6_Y1o&P3L=8~18fzU=G!ZhKAWPT>V!J6v@LtX6 z#hSH0s3FM%J&uWd*-_m`nsDyQov_Q9^TL~R`#9b*E@``(R~|ob^vjc1)YmWJLg&&l zv!`Pt_=dy`&4CcVw??s(2Y4B&4f~c*^is4aGGfzt9l~@Wl*tvBi|w6sB8W1O0&UZL&AwU$r2E?(o>5qL`_#`B0bjgn3kj^@|5t19;3jZsMtNVxjZSOTV zU#=Acs<Zd*WT*w>F$;RzW#tGstE|i>Et_?zo_1W&K(oXM&h=>;>t@!Bm#9b9103jqu#SaB6E&`E`$Siyk8;QTrJK2twa zd+2Ee8{SEU{+?^1KpA$hD3gC3pfH<`xh=f==sd$&b&l8T?I2&CPt5gR@~xxejzXio zldUWeiL|DF(%qw64NYg%ErPzsi~o*5`9IY-&#-ZA{`@hVQubQh7B|o3gR`La4g>rT6vW*R%0(_g9bAiEBRDQ)lC6DqeJyEO`UNV3?lL zYV}>cH0eG{S+QEY;Zn?}_bbQ`xF|{y^!nkd!%4*ClAZkxuuuld zDsp7-$)%3Btrgkt7qxTr-E zu#DXN@>m>b8oc=ZQa84X@E_sZGb!TOm{sHZ8C8k`C@{mQ(ac|~50nDQTb~Swsg`9j z5_L;1zv#m2#Ixqe_l)PnN?aL#;-Q_@+Sw@?C>`!4+}M%PK7DsVeCv&68F?XYlN)j2 z8Rkxb-{-+yqgqt9sa^BJTdQOlS|5)XqeugV{()PVTqU zI-tN92OD=={O;jbkBfFRjS05_-XA_J5h3d_H=sw*zsSRo3*Z8WB``Ca+8Sav(Vh%? z709P@TG7o*n&A1+Qd5U&o0$_&EKx2vW+5en$H*F+z`T~I11+ z(()c7RGcWr`*~W&NTx!<93# ze2q!(;-6M)_81l=|LhE{{S6-smQv36CU{dPkvQTzFWm4u(ZP-!QDsV9&ESz)6^gK! zkgqt({@o?>Y^nzw0c&CFy1tr0LKBGlMR&$MsG2!21d$W;kzwF?5$RWGp5~ce#6;aX z8peoR0=X4frt8D(`jtXPLF#t9!=^dPOhZCFk|@?mJcmW4@1-kb*cF+4bIgvuHY$&{ z%gKwCTX8>HLe8x7RO9H~*|66H8G5!1Z+(E0ak=NWD_r zAUIe>wBJf2w6{ygQwhBViPoMBpWZ%+p~gz%lm@tLTUYi8pVGdZRuSqqL?lDyfHW2R z41D23`Wh8sTG-AdAnVCy2ae`NCONOVETDC4FW@%)plY%e?4K}}>i)zihxrXqYu%Q< zB|Jnai|^PPzultXC-%Yp(G_H1A^Me><=I;(Co)%rgas6@RB0Cf-)e9c=6vG3pN~Wgt(+Gl2r!l&6{N1-Z!NXzRxLN=8tB2mvqovU~ zJB9RigO2UEarvv4*oqHP`8a`ly_>e%$3#g;{ZbehpQ1vvF)-Mcsw2;whrTE+e|LY{ zA1%9`9c^yr^EGT~@;D=PEE~0HddsO3CMO@5|A#wQxk{^4A7*uG1N?*Pl#$DO2x=lM ziqmZh!>Ij<{qmAQJHGJZQrL_73O@lMlxbCgJhN`zdl^Ax1oo_o>~4-u&w%zL+;+9D zkWT&+5IbXAZ!E#ws}KaB!ki-UKm-L7dHg4iz6j;nSfsC2(s7C}&2*wf->FlR4V>10 zI>ZZDkYVl?OO)JRGtSaz0V1c%d5iKM7}6 zmmF6NHySROa!S)KEW30L<)#AaE+NOP+AfV7MQr7FRy6~|n-VchjwaxpnZ$s4JLl)G zGRcRb*B)?9M8^r{xRBFGa2 zxvu%>&HC}nb85CJo=pPv`y{`-R^d2iM}=`IRqj^9l2r3#CS%(s>jRRhw-i&|B9jfk zdJ)qtra)I0NXdWr7ekYu4*u@~87v3QD) zsMq_YS?g!f@wswdmP_+Ms|hJCYb<@=xs(&zH~kznjgbed+2q}N9P z%_){-B|S<|nY|#|=^O^n1_2tgx31+G4rFNPh>T1dvER_GYf54}MRy?VM`yLhhL!E> zuvK)SnORjORxfpJgQlA4Ca3rBNUOA+T&uOrGRIhl4Pz$n^f_kjS?{-S_Qv{AC0+q9 zZQ1N7QM!9;-g``6-)U_`k}0csdIh@^*s*MEk*QA#jTp$27G^vXs~#k~T>mzbVC3BJ z{^+18e4o>>f$q7HYPFmq5=3nwdVc@?ml!4G);1hg z1H+Z2rN!`rg_QLZ;l;Lw%=X6C1N*?E@QR~xZr}Cf$?dQxMM{O_8~*#c=LER2s#4x6 z+y%9!XSC1e;|92mn5$Zj?}F*pv{F$Lq}5RiJ6X=L{*Y`(0A@W?wAQF!o#veX}i_qqOYaR33N5oe`=^ zm}Txvv^_-hcx~rny>vr{Rab6YQzbDI^ZjLAe<|-NQano5DqwP5)K&DeYoNn?ZbSjl zj7NL-LKB}uC9ihdJ6*`xPL5DXsbX$*IlQ`@s}`I8XsrMWc55wjq87~A@L_1=4D| z&8?aIi4mR`=xpy1M0K>aI2M~;(8|TjlQ3nBa)+1Rx)5F;(2#JJ^JB}u#CCo#dr72` zFz(8~zN~RGFf3fQjXy^us`N$AEmBAZ_qEh*F_O`FOHoGA%GHBW+yiRNLMnaS_geI& zZx4?na5p?*nGUxL?A_3{!HHwiz$VB7eEQA27<`9f`~}rRTnF6<=rmQ+Oix=z^~B2CMeS*Pa8<8d_A5(J9y?D6I2X zZC3-Gel}qOXWSrK&0IMdcd!%w<)TG_re}}j3l@@Zuu+lnW;^o_xT$q<;#BupyW>j5 z=`Q@Fg^IL?DG^*(cO%@>-dAW|@PO%qxkF$KHq_^)`};SHUwuK)k10->pmw(;JOJMRS8jX1qqO&lQTra_JYscbnIYNP)Vk}G z;b<~nXWCbq6M#(1Xs?pRmz$g2PNLl&Pcj(ET4t=PeDCsP(iU4wW0CU)Tnr}l$(a^Z z9TUC!ZJ2SCu3cOr*a}oVEEpW3B4h94aFh>{^N41C}zkQ4Jt=Ct5QC7t=de zW`&~EdmLgOah_+>7p3)0H;qHY$p%7km=hzL2q`^UG}tG|8M*Y4ntVv;>!XI>DJ0CB z8QgvFEj4jAuGLGX)zq)+2r*Z4XV-~tPSJr>o9BY3eEC3cFoE4&SHgn6k7=~fAR%$u za!f`!NX&z)C~F>mZG^TBI8BdCSS%_JINR0ZR&|x&iZ;D1spQs9C?DB$L)*oU!(Rpp z)S#%T9l1bF>#(24)X;YdZmdb!L8m>yF>JJ9m{gzBRGUdapg-A#>>w|4eUzx0DL@Xh zT_wBL?Fwt{?!%+1*p$8H-N3B6eLgFUfv1pw!JVaxSwHC_Z0T@D(l8_FeX=lL1)vCf zkxLYD8dCR>4BDu>RT>pm;A^;tL-h`h@PG=Qr(kRgk10AkniOVDpFc@h^lH_|*7h=h z&DBYnndd%%WZjRjIR@nuSYn{{O&k$1lwImDw^Bk2LzcIat&j8hszLwf@XnI&P&I2; zwBB$Pi{`r3f)TR3T6$g23E~j4wS=WEj2ELNQK|R&?<2O8kCr$jZJ?2D5-N2@6q zw|$2<_?8aciQ431`gXS-$uMq@v(pbY-;ZT|{S3pvWnu?XEFNgdUe0rKbCs%Hct;u} ze2#_tymD*|yrMiI@lb9S*?gPG4g}E>Z-3F3x&5*gdghMnyr03}@qNe0JWHV{*|u!O zbN2bJX&LV^MW+dqIxN9f;>aTL38OU4?hlIC<8$P64+VKNA%_Q^LBH=Ah44A8e}fR7!XmPB z6Q3uuqk#MNqWJ7wsmSRV#oYwH*@-hy zA5P?{(C0%TD{O}>nSANVmeo+|l4?X@o;#ZHjf%R?2LCMw*A^lE4~Z`nJ{GI?Zdp5^ z)4`MYH7tzLrMney9w4oo0Rn8H2B-(aPwxu`2@-4z?XVX`!q=S2Vsnj#O^M$kV3mB>E7fpM`DhBhaakW1E4GAArTLmqN_-{y9m94v5O}XlW61NkTd_S09rRV1WIbgehTJOgw0`lX+|9vFkWbW+Z05Y|(jQp&?A|o%u zEc0$_OIC(O5j4b1KREJbQek*RM&pwPlB0|Bnaea2BWP`FeJesyK`G|Th}`fWj362L z7$wHh5gC}`x2OIe{c8wC+*5_U}Q=*}nOvq*@;iR^Adr}7`^CTYqz1xopZ61pqMnL<^%e2spFd&klV zA|GDcTX2m;_e_D-#6OFOM1RPzg|*rseG~Ie>Xvf+B1@Iu!E7lA%-@AEbXG`Wp%qm< ztzsOTCunP_^*J{~;kf=_bg3?@Bf&$Ie#)-R|7>>%C9q`Btja#~J?3PMv{f$6{1}#7 zb0`dMoUIhmHwI~v1}qnvTT%~kD(3{69cBiymomnrf|1u=NrSk{XqMhyT#CJj-TPmr zZeTw8apDwl7NtH`F*A+2c#r%s{JGAJWksruBDm%C{iCj)A;vDzf~6Fr*=_$Zpc8c_ z2L^)I)}e-rvg|$}8I+~Ouahrc?}PkFudAXPeP%hKIV%lh)I_Hh$0oUe@;bOIr;vZC zO@U>ubZ!-aWapV~2pnqk^NW>L)J2NO(m9>JL~tiRW0a;VVs|C(s@kBatEoo}48q{O z+S&}`Eor<)W2b|~PW5@G2a6$umxXD#tgJ>NuSLN`Rq2tX#YdtjoBQ_tvVQx<)3K1V zr(+^1g%7>uzMiQx0-o6L#n~?TuLb^@a0!UB9B@Ap?Z+AeIDSvKf7=%zb4yDW>(>_c ztY+p8=C94nUz>Uu+F8H0bpkoNJ8!`LDQA8+L1_OL`Hw5|k1O(zEAo#k@{cR>|A8y= zvwSPjDn6P0DBF2It{=w8Zyxr)U6KFn2x>|is$vpqKQ{u@U$TR-keQi5R$-c{aFbDy zg@I*EPEjtj${!4){B`Qmd1<7j#`_Uq@20OL{K8K@)#z!A!gAKAH9i7celT(B?Nm$R zRLkbjEp(*i(B!aK_8fKHNp)D&No3-;okmuD0Tty(h(G!?0Mp-w>TK^|XlL$fZuc`- zrhi4a^>g!rfyD*<-#z>v-2XZ10)F29($W7j;;)RQe*pl1x`6T@KL`95;+M_zXUJc5 zp}!z~SieDj^`w7>{FR>k1rhxrFaIl&|ESA9GyX~g{$h;(HN(N<&xpTL8NU!!gujLH z@0kAIn&Wr=pZ~k~DLMZ4s0%J0$^ literal 0 HcmV?d00001 diff --git a/dist/Pyqtree-0.23.zip b/dist/Pyqtree-0.23.zip new file mode 100644 index 0000000000000000000000000000000000000000..f5663c4593882b225a0b5bf3e54d1554b9114037 GIT binary patch literal 8819 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 G!2bZh?!CS{HXh%|$W&M|xt1vcNNv8w zbcF@P-OO$ZqTaGEVla}@>{9Za8-w-OIYEY1jVBW!~B)c fA~f6#^;)OA}K