У меня есть массив точек с широтой и долготой, из этого массива, генерирующего 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))
Пожалуйста помоги!
Ваш вопрос серьезно нуждается в SSCCE. Читая его, вы можете искать что-нибудь от простого преобразования типов до сложных алгоритмов маршрутизации.
Вот два простых SSCCE, которые показывают, как выполнять преобразования типов, которые вы описываете.
НОТА Дополнительная работа для проверки правильности многоугольника (его необходимо закрыть, а точки должны иметь правильную ориентацию для внешнего кольца)
#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))
#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))
я нашел решение, это 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);
Пожалуйста, извините за плохой английский!