Boost C++ Libraries: Ticket #10615: R-Tree: add constructor that converts any range<T> to the trees value type https://svn.boost.org/trac10/ticket/10615 <p> I'd suggest adding a new constructor to rtree for bulk loading. It should take a range of any value and a function that converts the ranges value to the rtrees value. </p> <p> My use case would be a (in my example: random access) container of points I need to put into an rtree with rtree::value_type being std::pair&lt;point, container_index&gt;. At the moment I need to </p> <ol><li>transform my container of points to a container of pairs </li><li>bulk load that new container of pairs </li><li>let rtree constructor copy my container of pairs </li><li>delete my intermediate container of pairs </li></ol><p> I'd really like to move the transformation done in the first step into rtree ctor to avoid creating a temporary container just to copy it into rtree and destroy it immediately after the rtree is created. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10615 Trac 1.4.3 awulkiew Mon, 06 Oct 2014 09:03:05 GMT <link>https://svn.boost.org/trac10/ticket/10615#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10615#comment:1</guid> <description> <p> AFAIU this musn't be done in the ctor. Doesn't transform adaptor meet your needs? Should this proposed ctor work differently than the code below? I'd prefer to not extend the interface if it was really not necessary. </p> <pre class="wiki"> rtree rt1(values | boost::adaptors::transformed(fun)); rtree rt2(boost::adaptors::transform(values, fun)); </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 06 Oct 2014 13:35:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10615#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10615#comment:2</guid> <description> <p> Thanks for your quick reply. That seems like the solution I've searched for (though in the wrong spot as I've looked in rtree when Boost.Range might do the trick) but a first test gives me compile errors about missing <code>type</code> and <code>reference</code> typedefs in <code>boost::transform_iterator</code>, a missing class template named <code>result</code> in what seems to be the lambda function <code>fun</code> in your example and again no matching function for call to <code>begin(const boost::range_detail::transformed_range)</code> and <code>end</code> with the same signature as begin. </p> <p> So I'll try to sort out my problems and/or condense my code into a small example to seek further advice. Anyway, you can close this ticket, since even if constructing an rtree from an adapted range would fail right now your suggested solution is far more elegant and can be done without writing new library code. </p> <p> As a sidenote - I might have overlooked it - but an example of rtree creation from an adapted range would probably help some narrow-minded users like me to realize that Boost.Range isn't just a few templates you need to specialize in order to get your stuff into Geometry. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 06 Oct 2014 21:38:17 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10615#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10615#comment:3</guid> <description> <p> So again, thank you and consider this solved. After I found time to actually read the Boost.Range documentation and not just wildly try stuff out it was easy to adapt my code and remove the additional copying of the container of points. For future reference I'll post a more complete solution, since it was not immediately obvious to me that I needed to create a good old functor instead of a lambda. </p> <div class="wikipage" style="font-size: 80%"><div class="wiki-code"><div class="code"><pre><span class="k">class</span> <span class="nc">my_point</span><span class="p">;</span> <span class="c1">//a point type known to Boost.Geometry</span> <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">my_point</span><span class="o">&gt;</span> <span class="n">point_list</span><span class="p">;</span> <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">my_point</span><span class="p">,</span> <span class="n">point_list</span><span class="o">::</span><span class="n">size_type</span><span class="o">&gt;</span> <span class="n">indexed_point</span><span class="p">;</span> <span class="k">struct</span> <span class="n">add_index</span> <span class="p">{</span> <span class="k">typedef</span> <span class="n">indexed_point</span> <span class="n">result_type</span><span class="p">;</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="kr">inline</span> <span class="n">result_type</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">T</span> <span class="o">&amp;</span><span class="n">v</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">make_pair</span><span class="p">(</span><span class="n">v</span><span class="p">.</span><span class="n">value</span><span class="p">(),</span> <span class="n">v</span><span class="p">.</span><span class="n">index</span><span class="p">());</span> <span class="p">}</span> <span class="p">};</span> <span class="n">point_list</span> <span class="n">p</span><span class="p">;</span> <span class="c1">//fill with points</span> <span class="n">rtree</span><span class="o">&lt;</span><span class="n">indexed_point</span><span class="p">,</span> <span class="cm">/*Parameters*/</span><span class="o">&gt;</span> <span class="n">rt1</span><span class="p">(</span><span class="n">p</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">adaptors</span><span class="o">::</span><span class="n">indexed</span><span class="p">()</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">adaptors</span><span class="o">::</span><span class="n">transformed</span><span class="p">(</span><span class="n">add_index</span><span class="p">()));</span> </pre></div></div></div><p> Thanks again for your hint and sorry for the noise in here. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>awulkiew</dc:creator> <pubDate>Tue, 07 Oct 2014 10:46:08 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/10615#comment:4 https://svn.boost.org/trac10/ticket/10615#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> In my original example there is only transformed() used because initially I thought about calculating the index of a Point using iterator/pointer arithmetic, so something rather unsafe because if we at some later time changed vector to some other container the indexes would be invalid. So your solution using indexed() adaptor is more "correct". </p> <p> Actually I thought that transformed() requires standard unary predicates like STL algorithms to e.g. support lambda functions. But now when I think of it, it'd require C++11 or Boost.<a class="missing wiki">TypeOf</a>. Anyway it's inconvenient that it doesn't. If it did then e.g. in C++14 we could write: </p> <pre class="wiki">// This doesn't work for now rtree&lt;indexed_point, /*Parameters*/&gt; rt1(p | boost::adaptors::indexed() | boost::adaptors::transformed( [](auto v) { return std::make_pair(v.value(), v.index()); } )); </pre><p> Regarding the docs/example, the docs and the code can always be improved. I expect that your use case is quite common so an example could be helpful. </p> <p> There is a hint in the docs, in the section <em>Queries</em>-&gt;<em>Inserting query results into the other R-tree</em>: </p> <p> <em>You may pass the result Range directly into the constructor or insert() member function.</em> </p> <pre class="wiki">RTree rt4(rt1 | bgi::adaptors::queried(bgi::intersects(Box(/*...*/))))); </pre><p> but maybe something similar should be placed in the section <em>Creation and Modification</em> since it may be not obvious how Boost.Range and the rtree could be used together. </p> <p> Thanks for suggestions! </p> Ticket