Nikola
Nikola

Reputation: 61

Convert array of point to polygon

I have array of point with latitude and longitude, from this array generating LineString to display way on road by leaflet.

Now i want to improve code function to detect when user point (received from GPS device):

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

After having tried many ways to implement my idea i coming to convert my array of point to Polygon and control by boost::geometry::intersection

I tried realise this function by search near point in array that work perfect in one way road else code can lock point from neighbour way :(

Example of ways:

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

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

Now i want to convert array to one polygon

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

i think that i can easily release function to detect location without errors

May be someone know how easily convert linestring to polygon?

example

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))

Please help!

Upvotes: 0

Views: 1515

Answers (2)

Nikola
Nikola

Reputation: 61

i found solution this is 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);

Please sorry for bad english!

Upvotes: 0

sehe
sehe

Reputation: 393959

Your question is in serious need of a SSCCE. Reading it you might be looking for anything from trivial type conversion to complicated routing algorithms.

Here's are two simple SSCCE's that show how to do the type conversions you describe.

NOTE The extra work to check that the polygon is valid (it needs to be closed, and the points need to have the correct orientation for the outer ring)

Array Of Point 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 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";
}

Prints:

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";
}

Prints

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))

Upvotes: 1

Related Questions