将数组转换为多边形

时间:2017-09-30 08:00:51

标签: c++ boost geometry point-in-polygon boost-geometry

我有纬度和经度的点数组,从这个数组生成LineString,通过传单在路上显示方式。

现在我想改进代码功能来检测用户点(从GPS设备接收)的时间:

1) Out from waypoint
2) Position on waypoint
3) Direction (begin or back)

在尝试了很多方法来实现我的想法后,我将我的点数转换为Polygon并通过boost :: geometry :: intersection

进行控制

我尝试通过搜索阵列中的近点来实现此功能,这种方式在单向路上工作完美,否则代码可以从邻居方式锁定点:(

方式示例:

[start]--------------[end]

But it can be so
[start]
---------one_road---turning_road_and_reverse-]
-------two_road-----------
[end]

现在我想将数组转换为一个多边形

-----------------------------------------------
one_road
two_road
-----------------------------------------------

我认为我可以轻松释放功能以无错误地检测位置

可能有人知道如何轻松地将线串转换为多边形?

例如

i have:
LINESTRING(-105.40392744645942 38.49004450086558,-105.40486621961463 38.491262147649266,-105.40443706617225 38.49272329662804,-105.40424394712318 38.49368058506501,-105.4055099497782 38.49443633010962,-105.40690469846595 38.494940155735165,-105.40694761381019 38.49450350706328,-105.40634679899085 38.49324392875914,-105.40510225400794 38.49146368720108,-105.40437269315589 38.490422393448746,-105.40394675757852 38.489957795386)

i want:

POLYGON((-105.40419674129225 38.49056599190572,-105.40475464076735 38.49046522094479,-105.40737247676589 38.494462360981586,-105.40685749263503 38.49520130375959,-105.40647554502357 38.493848529093356,-105.4052739153849 38.49193394396309,-105.4047160159098 38.49237060820819,-105.40473747358192 38.49344546276763,-105.40600347623695 38.49430197601443,-105.40664720640052 38.49480580257953,-105.40585327253211 38.494789008417456,-105.40432977781165 38.49394929532246,-105.40394353971351 38.493059188756156,-105.40465164289344 38.49129573761371,-105.40419674129225 38.49056599190572))

请帮忙!

2 个答案:

答案 0 :(得分:1)

您的问题非常需要SSCCE。阅读它你可能正在寻找从简单的类型转换到复杂的路由算法的任何东西。

以下是两个简单的SSCCE,展示了如何进行您描述的类型转换。

  

注意检查多边形是否有效的额外工作(需要关闭它,并且点需要具有正确的外环方向)

点到多边形的数组

<强> Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/polygon.hpp>

#include <iostream>
#include <boost/geometry/io/io.hpp>

namespace bg = boost::geometry;
namespace bgm = bg::model;

using point      = bgm::d2::point_xy<int>;
using polygon    = bgm::polygon<point>;

void debug_print(polygon const& p) {
    std::string reason;
    bool valid = bg::is_valid(p, reason);
    std::cout << bg::dsv(p) << " - " << (!valid?"invalid ("+reason+")":"valid") << "\n";
}

int main() {

    point arr[] { {1,3}, {4,5}, {9, 0} };
    for (auto& p : arr)
        std::cout << bg::wkt(p) << " ";
    std::cout << "\n";

    polygon p { {std::begin(arr), std::end(arr)} };
    debug_print(p);

    bg::correct(p);
    debug_print(p);

    std::cout << bg::wkt(p) << "\n";
}

打印:

POINT(1 3) POINT(4 5) POINT(9 0) 
(((1, 3), (4, 5), (9, 0))) - invalid (Geometry has too few points)
(((1, 3), (4, 5), (9, 0), (1, 3))) - valid
POLYGON((1 3,4 5,9 0,1 3))

LineString To Polygon

<强> Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/polygon.hpp>

#include <iostream>
#include <boost/geometry/io/io.hpp>

namespace bg = boost::geometry;
namespace bgm = bg::model;

using point      = bgm::d2::point_xy<int>;
using linestring = bgm::linestring<point>;
using ring       = bgm::ring<point>;
using polygon    = bgm::polygon<point>;

void debug_print(polygon const& p) {
    std::string reason;
    bool valid = bg::is_valid(p, reason);
    std::cout << bg::dsv(p) << " - " << (!valid?"invalid ("+reason+")":"valid") << "\n";
}

int main() {

    linestring ls { {1,3}, {4,5}, {9, 0} };
    std::cout << bg::wkt(ls) << "\n";

    polygon p { ring{ls.begin(), ls.end()} };
    debug_print(p);

    bg::correct(p);
    debug_print(p);

    std::cout << bg::wkt(p) << "\n";
}

打印

LINESTRING(1 3,4 5,9 0)
(((1, 3), (4, 5), (9, 0))) - invalid (Geometry has too few points)
(((1, 3), (4, 5), (9, 0), (1, 3))) - valid
POLYGON((1 3,4 5,9 0,1 3))

答案 1 :(得分:0)

我发现解决方案是boost :: geometry :: buffer

using namespace boost::geometry::model;
namespace bg = boost::geometry; 
typedef  bg::model::point <double , 2, bg::cs::cartesian > point_t;
typedef boost::geometry::model::polygon <point_t> polygon_t;
typedef bg::model::linestring<point_t> linestring_t;
linestring_t ls1;


vector<BSONElement> point_records = record.getField("points").Array();
    linestring_t ls1;
    for(vector<BSONElement>::iterator it = point_records.begin(); it != point_records.end(); ++it)
    {
        BSONObj point_record = (*it).Obj();

        bg::append(ls1, point_t(point_record.getField("lo").Double(), point_record.getField("lat").Double()));
    }


 const double buffer_distance = 1.0;
    const int points_per_circle = 36;
     // Declare other strategies
    boost::geometry::strategy::buffer::distance_symmetric<double> distance_strategy(0.0002);
    boost::geometry::strategy::buffer::join_round join_strategy(points_per_circle);
    boost::geometry::strategy::buffer::end_round end_strategy(points_per_circle);
    boost::geometry::strategy::buffer::point_circle circle_strategy(points_per_circle);
    boost::geometry::strategy::buffer::side_straight side_strategy;
       boost::geometry::model::multi_polygon<polygon_t> result; 
    /* polygon_t result; */
    boost::geometry::buffer(ls1, result,
                distance_strategy, side_strategy,
                join_strategy, end_strategy, circle_strategy);

抱歉英语不好!