将点数组转换为多边形
Convert array of point to polygon
我有经纬度点数组,从这个数组生成 LineString 以通过传单显示道路。
现在我想改进代码功能来检测用户何时指向(从 GPS 设备接收):
1) Out from waypoint
2) Position on waypoint
3) Direction (begin or back)
在尝试了很多方法来实现我的想法之后,我开始将我的点数组转换为多边形并通过 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,展示了如何进行您描述的类型转换。
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)
点数组到多边形
#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);
英语不好请见谅!
我有经纬度点数组,从这个数组生成 LineString 以通过传单显示道路。
现在我想改进代码功能来检测用户何时指向(从 GPS 设备接收):
1) Out from waypoint
2) Position on waypoint
3) Direction (begin or back)
在尝试了很多方法来实现我的想法之后,我开始将我的点数组转换为多边形并通过 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,展示了如何进行您描述的类型转换。
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)
点数组到多边形
#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);
英语不好请见谅!