<html>
<head>
        <title></title>
        
<meta name="GENERATOR" content="MSHTML 8.00.6001.18852"></meta>
</head>

<body>
        
<div align="left">I think I was complicating things way to much last week.</div>
        
<div align="left"> </div>
        
<div align="left">Some car trips later I think like this :-)</div>
        
<div align="left">keep all structures and treebuilding. first do a deepdive in the tree (or climbing maybe), for each level check which child is closest to the other geometries center of bbox.</div>
        
<div align="left">The distance between the leafes found that way should give a good first mindistance. In many cases the right answer will be found already here. But to find out we have to do it all from the beginning like it works now, but with a better mindistance to start with.</div>
        
<div align="left"> </div>
        
<div align="left">I realise I should have tested to order all vertexes from "distance to corresponding center of bbox" in my algoritm instead of what I'm doing now. It would have been nicer code. I don't know if it would have been faster and I don't know if I then could find when I was done. But I havenŠt considered the possibility.</div>
        
<div align="left"> </div>
        
<div align="left">This tree of yours Paul, should work great with 3D too, shouldn't it?</div>
        
<div align="left">Just making the nodes representing boxes instead of surfaces.</div>
        
<div align="left"> </div>
        
<div align="left">/Nicklas<br />
                <br />
                2009-12-02 Nicklas Avén wrote:<br />
                <br />
                The car trip to work gave me some more rounds of thinking. ></div>
        
<div align="left"> </div>>
        
<div align="left">The idea have to be developed. It shouldn't matter how many childen we find optimal. </div>>
        
<div align="left">The thing is to find the best way of storing which one of the children that represents maxX, maxY and so on, so we can do the right diving.</div>>
        
<div align="left">It shouldn't cost anything extra (almost), the information is there in <strong>rect_node_internal_new(),</strong> we just have to store it.</div>>
        
<div align="left"> </div>>
        
<div align="left">/Nicklas</div>>
        
<div align="left"> </div>>
        
<div align="left"> </div>>
        
<div align="left"><strong></strong></div>>
        
<div align="left"><strong> </strong>2009-12-02 Nicklas Avén wrote:<br />
                ><br />
                > Yes, I see what you mean. I thought about it too. ></div>>
        
<div align="left"> </div>> >
        
<div align="left">But what about mixing all ideas in one.</div>> >
        
<div align="left">I think I maybe was struck by an idea about it this morning, worth considering.</div>> >
        
<div align="left">What about giving every parent 4 children. And then in the optimal node have one child with maxX, one with maxY, one minX and one minY. Probably it will be the same child that in reality has two or more positions, but then identify that it is the same and force the fourth child to that place, so the place for , say maxX is hold by a child with no internal max or min value (good enough)</div>> >
        
<div align="left"> </div>> >
        
<div align="left">Then to get a overall direction between the geometries, compare the center of the boundingboxes and decide if the direction falls under nort, south, west or east.</div>> >
        
<div align="left">So for two geometries that is west and east of each other we start deepdiving in the west respectively east corner of the nodes all the way domn to the leaf and get a first fairly good mindistance very fast. Then we can do the rest with a better min distance to sort away the ones too far away for considering.</div>> >
        
<div align="left"> </div>> >
        
<div align="left">Does it make any sense?</div>> >
        
<div align="left"> </div>> >
        
<div align="left">I'm in a hurrry so maybe not to structured.</div>> >
        
<div align="left"> </div>> >
        
<div align="left">/Nicklas<br />
                > ><br />
                > > 2009-12-01 Paul Ramsey wrote:<br />
                > ><br />
                > > I'm thinking that the worst-case behavior of the tree traversal could<br />
                > > >also be a lot worse than the worse case behavior of the sort solution<br />
                > > >(the recursion seems to provide a depth-first search, and if the first<br />
                > > >stab is fairly far from the closest distance, it could take a while to<br />
                > > >prune back the tree towards the optimum). Getting the most out of the<br />
                > > >tree is almost certainly going to require caching.<br />
                > > ><br />
                > > >P.<br />
                > > ><br />
                > > >On Tue, Dec 1, 2009 at 11:12 AM, Nicklas Avén<br />
                > > > .aven@jordogskog.no> wrote:<br />
                > > >> Yes, I think you are right that my mistake was to use malloc.<br />
                > > >> /Nicklas<br />
                > > >><br />
                > > >> 2009-12-01 Paul Ramsey wrote:<br />
                > > >><br />
                > > >> Nick,<br />
                > > >>><br />
                > > >>>You asked if maybe you did something naive and the answer is "possibly<br />
                > > >>>yes". For example, if you did your allocations using malloc() you got<br />
                > > >>>a much more expensive heap allocation than if you used palloc() (or<br />
                > > >>>lwalloc() in the context of a pgsql build).<br />
                > > >>><br />
                > > >>>But anyhow, yes, knowing the number of edges before-hand, and knowing<br />
                > > >>>our tree building scheme, we could easily allocate the whole segment<br />
                > > >>>in one go at the start (~1.5 * npoints * sizeof(node)).<br />
                > > >>><br />
                > > >>>For 2.0, I've been thinking about the way to make this stuff "real",<br />
                > > >>>and I'm pretty sure the answer is to stick an extra handle on<br />
                > > >>>POINTARRAY for holding these optional structures. Then, an<br />
                > > >>>lwgeom_index(LWGEOM *g) function would walk into an LWGEOM, ensure all<br />
                > > >>>the *bbox pointers are filled in, and build the trees on all the<br />
                > > >>>POINTARRAYs. Then the whole thing could be neatly cached, if<br />
                > > >>>necessary, etc.<br />
                > > >>><br />
                > > >>>P.<br />
                > > >>><br />
                > > >>>On Tue, Dec 1, 2009 at 10:16 AM, Nicklas Avén<br />
                > > >>> wrote:<br />
                > > >>>> aul<br />
                > > >>>> If it is as I suspect that the number of memory allocations is the most<br />
                > > >>>> costly part of this, wouldn't it be possible to allocate all of it once<br />
                > > >>>> and<br />
                > > >>>> for all. If you allocate one list of nodes for each level, the whole<br />
                > > >>>> structure of the tree is given. You know where the children and parents<br />
                > > >>>> is<br />
                > > >>>> related to the start of the "level lists" the only thing missing is the<br />
                > > >>>> min<br />
                > > >>>> and max x any y for each level.<br />
                > > >>>><br />
                > > >>>> /Nicklas<br />
                > > >>>><br />
                > > >>>> 2009-12-01 Nicklas Avén wrote:<br />
                > > >>>><br />
                > > >>>> :-) ><br />
                > > >>>><br />
                > > >>>><br />
                > > >>>>><br />
                > > >>>> I think I see what you are doing<br />
                > > >>>>><br />
                > > >>>> Had to take another look...<br />
                > > >>>>><br />
                > > >>>><br />
                > > >>>>><br />
                > > >>>> The comarasion part is the same as I used for subgeometries and as you<br />
                > > >>>> say<br />
                > > >>>> (I saw the blog too) the natural ordering of the edges should make the<br />
                > > >>>> tree<br />
                > > >>>> very effective.<br />
                > > >>>>><br />
                > > >>>><br />
                > > >>>>><br />
                > > >>>> But I think you have to cache the tree to beat my calculation :-)<br />
                > > >>>>><br />
                > > >>>> That belive comes from some trying I did when writing the code, before I<br />
                > > >>>> had<br />
                > > >>>> found the qsort function. Then I build a tree as described in that<br />
                > > >>>> C-bible I<br />
                > > >>>> can't remember the name, just to get the measure-values ordered. I think<br />
                > > >>>> it<br />
                > > >>>> was the number of memory-allocations that showed to be very expensive. I<br />
                > > >>>> might have done som elementary mistake but when I tried that tree with<br />
                > > >>>> one<br />
                > > >>>> node per vertex on the largest polygon of Alaska (about 70000 vertexes)<br />
                > > >>>> it<br />
                > > >>>> used almost 7 seconds just to build the tree and read it ordered. The<br />
                > > >>>> whole<br />
                > > >>>> calculation for distance between the largest polygons in Alaska and Texas<br />
                > > >>>> now uses less than 100 ms. But it is quite likely that I had done som<br />
                > > >>>> mistake in my treebuilding.<br />
                > > >>>>><br />
                > > >>>> (That calculation Alaska Texas is extremly fast because Texas has that<br />
                > > >>>> sharp<br />
                > > >>>> edge aginst Alaska which is easy for my algoritm to catch.)<br />
                > > >>>>><br />
                > > >>>><br />
                > > >>>>><br />
                > > >>>> /Nicklas<br />
                > > >>>>><br />
                > > >>>>><br />
                > > >>>><br />
                > > >>>>><br />
                > > >>>><br />
                > > >>>>><br />
                > > >>>>> 2009-12-01 Nicklas Avén wrote:<br />
                > > >>>>><br />
                > > >>>>> ><br />
                > > >>>>><br />
                > > >>>> wow, I think postgis will be hard to beat in the long run :-)<br />
                > > >>>>> ><br />
                > > >>>><br />
                > > >>>>> ><br />
                > > >>>> I'm not used to study those tree things, but it will be very interesting<br />
                > > >>>> to<br />
                > > >>>> follow this and try to understand it.<br />
                > > >>>>> ><br />
                > > >>>> Will it work on overlapping bboxes too?<br />
                > > >>>>> ><br />
                > > >>>><br />
                > > >>>>> ><br />
                > > >>>> One thing I think is nice about "my" way of doing it, is that there is no<br />
                > > >>>> indexes included. The gain is that it can be nested in subqueries<br />
                > > >>>> and CTE's<br />
                > > >>>> without loosing the speed. But I haven't really understood when that<br />
                > > >>>> problem<br />
                > > >>>> occur of not using the indexes.<br />
                > > >>>>> ><br />
                > > >>>><br />
                > > >>>>> ><br />
                > > >>>> I have been thinking some in 3D terms too, totally without knowledge<br />
                > > >>>> about<br />
                > > >>>> reality. But it shouldn't be too impossible to do the same tricks in 3D<br />
                > > >>>> and<br />
                > > >>>> calculating point to surface instead of point to segment. But that would<br />
                > > >>>> need a 3D type. I don't know how that use to be built, but I have<br />
                > > >>>> imagined a<br />
                > > >>>> list of 3D points and a related list with pointidentifiers in groups of<br />
                > > >>>> three, defining triangels. Then it would be quite fast to do like my<br />
                > > >>>> distance trick on the points and finding the surfaces to calculate<br />
                > > >>>> distances<br />
                > > >>>> to with some index on the pointidentifiers list...<br />
                > > >>>>> ><br />
                > > >>>><br />
                > > >>>>> ><br />
                > > >>>> /Nicklas<br />
                > > >>>>> ><br />
                > > >>>><br />
                > > >>>>> ><br />
                > > >>>><br />
                > > >>>>> ><br />
                > > >>>>> ><br />
                > > >>>>> > 2009-12-01 Paul Ramsey wrote:<br />
                > > >>>>> ><br />
                > > >>>>> > Niklas,<br />
                > > >>>>> > ><br />
                > > >>>>> > >Your cunning sorting trick got into my head and I thought and thought<br />
                > > >>>>> > >on it and ended up borrowing the magic tree idea from Mark's prepared<br />
                > > >>>>> > >p-i-p code, and added another dimension to that, so the trees are<br />
                > > >>>>> > >actually in 2d space, and then starting thinking about how, given two<br />
                > > >>>>> > >of these trees you could quickly find things like intersections or<br />
                > > >>>>> > >even (*gasp*) distances...<br />
                > > >>>>> > ><br />
                > > >>>>> > >geog=# select distance(buffer('POINT(3 3)', 2),buffer('POINT(0 0)',<br />
                > > >>>>> > > 2));<br />
                > > >>>>> > > distance<br />
                > > >>>>> > >-------------------<br />
                > > >>>>> > > 0.242640687119285<br />
                > > >>>>> > >(1 row)<br />
                > > >>>>> > ><br />
                > > >>>>> > >geog=# select npoints(buffer('POINT(3 3)', 2));<br />
                > > >>>>> > > npoints<br />
                > > >>>>> > >---------<br />
                > > >>>>> > > 33<br />
                > > >>>>> > >(1 row)<br />
                > > >>>>> > ><br />
                > > >>>>> > >geog=# select 33*33;<br />
                > > >>>>> > > ?column?<br />
                > > >>>>> > >----------<br />
                > > >>>>> > > 1089<br />
                > > >>>>> > >(1 row)<br />
                > > >>>>> > ><br />
                > > >>>>> > >These two circles have 33 points each, so the brute force method<br />
                > > >>>>> > >requires 1089 distance calculations to come up with an answer. The<br />
                > > >>>>> > >magic trees took 29. It's also possible to *cache* the trees and<br />
                > > >>>>> > >re-use them, both for distance calculations and intersections and<br />
                > > >>>>> > >containments.<br />
                > > >>>>> > ><br />
                > > >>>>> > >Very exciting stuffs!<br />
                > > >>>>> > ><br />
                > > >>>>> > >However, we're almost to 1.5 and adding all the features you already<br />
                > > >>>>> > >have in your code (maximums, points and lines of shortness, etc)<br />
                > > >>>>> > > would<br />
                > > >>>>> > >take way too long. And I'm not sure my code is actually faster. Just<br />
                > > >>>>> > >that it's much faster than the brute force ways.<br />
                > > >>>>> > ><br />
                > > >>>>> > >It's all in lwtree.c in liblwgeom if you want to look.<br />
                > > >>>>> > ><br />
                > > >>>>> > >P.<br />
                > > >>>>> > >_______________________________________________<br />
                > > >>>>> > >postgis-devel mailing list<br />
                > > >>>>> > >postgis-devel@postgis.refractions.net<br />
                > > >>>>> > >postgis.refractions.net/mailman/listinfo/postgis-devel<br />
                > > >>>>> > ><br />
                > > >>>>> > ><br />
                > > >>>> _______________________________________________<br />
                > > >>>> postgis-devel mailing list<br />
                > > >>>> postgis-devel@postgis.refractions.net<br />
                > > >>>> http://postgis.refractions.net/mailman/listinfo/postgis-devel<br />
                > > >>>><br />
                > > >>>><br />
                > > >>>_______________________________________________<br />
                > > >>>postgis-devel mailing list<br />
                > > >>>postgis-devel@postgis.refractions.net<br />
                > > >>>postgis.refractions.net/mailman/listinfo/postgis-devel<br />
                > > >>><br />
                > > >>><br />
                > > >> _______________________________________________<br />
                > > >> postgis-devel mailing list<br />
                > > >> postgis-devel@postgis.refractions.net<br />
                > > >> http://postgis.refractions.net/mailman/listinfo/postgis-devel<br />
                > > >><br />
                > > >><br />
                > > >_______________________________________________<br />
                > > >postgis-devel mailing list<br />
                > > >postgis-devel@postgis.refractions.net<br />
                > > >postgis.refractions.net/mailman/listinfo/postgis-devel<br />
                > > ><br />
                > > ></div>
</body>
</html>