|
Boost Users : |
From: Mateusz Loskot (mateusz_at_[hidden])
Date: 2019-10-03 17:30:30
On Thu, 3 Oct 2019 at 18:04, Giorgino R via Boost-users
<boost-users_at_[hidden]> wrote:
>
> Is there any boost functionality to "split" a linestring with an intersecting point?
I'm not aware of any such algorithm in Boost.Geometry.
> I was expecting that boost::geometry::intersection could return a multi-linestring (of size two) or a vector of linestrings (size two).
That would be a different algorithm, presumably split, but not
intersection according to OGC.
Mind you, the Boost.Geometry documentation at
https://www.boost.org/libs/geometry/doc/html/geometry/reference/algorithms/intersection/intersection_3.html
says "The function intersection implements function Intersection from
the OGC Simple Feature Specification.",
what is similar to PostGIS, https://postgis.net/docs/ST_Intersection.html.
The OGC Simple Feature Specification says the algorithm returns
point set intersection of input geometries.
> For example, please see a very simple case below which doesn't compile:
>
>> point_2d pt(0.5, 0);
>> linestring_2d ls({ point_2d(0, 0), point_2d(1, 0), point_2d(3, 0), point_2d(5, 0) });
>> std::vector<linestring_2d> inter;
>> bg::intersection(pt, ls, inter);
>
>
> Is there any way to get inter vector with two linestrings (...) or any multi geometry container
> that will hold the spatial information of two lines connected in this point?
> Or should I create these two lines myself by working out which points of the linestring
> are left and right of the intersecting point?
There is a way and yes you need to build a solution your self,
but it should be not a hair-pulling experience using the building blocks
provided by Boost.Geometry.
For example, here is a quick example with possible solution:
```
#include <boost/geometry.hpp>
#include <algorithm>
#include <iostream>
#include <vector>
namespace bg = boost::geometry;
using point_2d = bg::model::d2::point_xy<double>;
using linestring_2d = bg::model::linestring<point_2d>;
int main()
{
point_2d pt(2.5, 0);
linestring_2d ls({{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}});
auto split_begin = std::find_if(bg::segments_begin(ls),
bg::segments_end(ls),
[&pt](auto const& segment) { return bg::intersects(segment, pt); });
linestring_2d line1;
std::for_each(bg::segments_begin(ls), split_begin, [&line1](auto const& s)
{
bg::append(line1, s.first);
});
bg::append(line1, split_begin->first);
bg::append(line1, pt);
linestring_2d line2;
bg::append(line2, pt);
bg::append(line2, split_begin->second);
std::for_each(++split_begin, bg::segments_end(ls), [&line2](auto const& s)
{
bg::append(line2, s.second);
});
std::cout << bg::dsv(line1) << std::endl;
std::cout << bg::dsv(line2) << std::endl;
}
```
It does take some time to get familiar with Geometry LEGO, but the docs are good
and the .cpp files with examples should be useful as well.
Best regards,
-- Mateusz Loskot, http://mateusz.loskot.net
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net