Skip to content

Commit 6abc088

Browse files
authored
Misc updates (#16)
* add iter version of douglas simplify, sync from https://github.com/cubao/pybind11-rdp * add range to segment index, t * fix * test for dir * fix polyline dir, update test * update version * update header * update header * update pybind11 * fix CI * fix CI * fix * fix * update headers * test douglas, update docs
1 parent 0f57b0e commit 6abc088

File tree

9 files changed

+253
-55
lines changed

9 files changed

+253
-55
lines changed

.pre-commit-config.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ repos:
3232
- id: mixed-line-ending
3333
- id: requirements-txt-fixer
3434
- id: trailing-whitespace
35-
- id: end-of-file-fixer
3635

3736
# Black, the code formatter, natively supports pre-commit
3837
- repo: https://github.com/psf/black

docs/about/release-notes.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ To upgrade `polyline-ruler` to the latest version, use pip:
1010
pip install -U polyline-ruler
1111
```
1212

13+
## Version 0.0.4 (2023-03-11)
14+
15+
* Misc updates
16+
* Update dir logic
17+
* Integrate douglas_simplify iter
18+
1319
## Version 0.0.3 (2023-03-05)
1420

1521
* Use GitHub workflow to release to pypi

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ nav:
1515
- License: about/license.md
1616
plugins:
1717
- include-markdown
18-
copyright: Copyright &copy; 2023 <a href="https://github.com/cubao">cubao team</a>.
18+
copyright: Copyright &copy; 2023 <a href="https://cubao.readthedocs.io">cubao team</a>.

pybind11

Submodule pybind11 updated 181 files

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def build_extension(self, ext):
122122
# logic and declaration, and simpler if you include description/version in a file.
123123
setup(
124124
name="polyline_ruler",
125-
version="0.0.3",
125+
version="0.0.4",
126126
author="tzx",
127127
author_email="dvorak4tzx@gmail.com",
128128
url="https://polyline-ruler.readthedocs.io",

src/polyline_ruler.hpp

Lines changed: 117 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <Eigen/Core>
1515
#include <optional>
16+
#include <queue>
1617

1718
#include "cheap_ruler.hpp"
1819
#include "crs_transform.hpp"
@@ -291,6 +292,22 @@ struct PolylineRuler
291292
return ranges[seg_idx] * (1.0 - t) + ranges[seg_idx + 1] * t;
292293
}
293294

295+
int segment_index(double range) const
296+
{
297+
const double *ranges = this->ranges().data();
298+
int I = std::upper_bound(ranges, ranges + N_, range) - ranges;
299+
return std::min(std::max(0, I - 1), N_ - 2);
300+
}
301+
302+
std::pair<int, double> segment_index_t(double range) const
303+
{
304+
const double *ranges = this->ranges().data();
305+
int I = std::upper_bound(ranges, ranges + N_, range) - ranges;
306+
int i = std::min(std::max(0, I - 1), N_ - 2);
307+
double t = (range - ranges[i]) / (ranges[i + 1] - ranges[i]);
308+
return {i, t};
309+
}
310+
294311
double length() const { return ranges()[N_ - 1]; }
295312

296313
static RowVectors dirs(const Eigen::Ref<const RowVectors> &polyline,
@@ -352,42 +369,31 @@ struct PolylineRuler
352369
return *dirs_;
353370
}
354371

372+
Eigen::Vector3d dir(int pt_index) const
373+
{
374+
return dirs().row(std::min(pt_index, N_ - 2));
375+
}
376+
355377
Eigen::Vector3d dir(double range, bool smooth_joint = true) const
356378
{
379+
if (!smooth_joint) {
380+
return dir(segment_index(range));
381+
}
382+
auto [i, t] = segment_index_t(range);
357383
auto &dirs = this->dirs();
358-
if (range <= 0.0) {
384+
if (i == 0) {
359385
return dirs.row(0);
360-
}
361-
auto &ranges = this->ranges();
362-
int i = 0;
363-
while (i + 1 < N_ && ranges[i + 1] < range) {
364-
++i;
365-
}
366-
if (smooth_joint && i + 1 < N_ && ranges[i + 1] == range) {
367-
Eigen::Vector3d dir = dirs.row(i + 1) + dirs.row(i);
386+
} else if (t == 0) {
387+
Eigen::Vector3d dir = dirs.row(i - 1) + dirs.row(i);
368388
return dir / dir.norm();
389+
} else {
390+
return dirs.row(i);
369391
}
370-
return dirs.row(std::min(i, (int)dirs.rows() - 1));
371392
}
372393

373394
Eigen::Vector3d extended_along(double range) const
374395
{
375-
auto &ranges = this->ranges();
376-
if (range <= 0.0) {
377-
double t = range / ranges[1];
378-
return interpolate(polyline_.row(0), polyline_.row(1), t,
379-
is_wgs84_);
380-
} else if (range >= length()) {
381-
double t =
382-
(range - ranges[N_ - 2]) / (ranges[N_ - 1] - ranges[N_ - 2]);
383-
return interpolate(polyline_.row(N_ - 2), polyline_.row(N_ - 1), t,
384-
is_wgs84_);
385-
}
386-
int i = 0;
387-
while (i + 1 < N_ && ranges[i + 1] < range) {
388-
++i;
389-
}
390-
double t = (range - ranges[i]) / (ranges[i + 1] - ranges[i]);
396+
auto [i, t] = segment_index_t(range);
391397
return interpolate(polyline_.row(i), polyline_.row(i + 1), t,
392398
is_wgs84_);
393399
}
@@ -742,31 +748,103 @@ inline void douglas_simplify(const Eigen::Ref<const RowVectors> &coords,
742748
douglas_simplify(coords, to_keep, max_index, j, epsilon);
743749
}
744750

745-
inline Eigen::VectorXi
746-
douglas_simplify_mask(const Eigen::Ref<const RowVectors> &coords,
747-
double epsilon, bool is_wgs84 = false)
751+
void douglas_simplify_iter(const Eigen::Ref<const RowVectors> &coords,
752+
Eigen::VectorXi &to_keep, const double epsilon)
753+
{
754+
std::queue<std::pair<int, int>> q;
755+
q.push({0, to_keep.size() - 1});
756+
while (!q.empty()) {
757+
int i = q.front().first;
758+
int j = q.front().second;
759+
q.pop();
760+
to_keep[i] = to_keep[j] = 1;
761+
if (j - i <= 1) {
762+
continue;
763+
}
764+
LineSegment line(coords.row(i), coords.row(j));
765+
double max_dist2 = 0.0;
766+
int max_index = i;
767+
for (int k = i + 1; k < j; ++k) {
768+
double dist2 = line.distance2(coords.row(k));
769+
if (dist2 > max_dist2) {
770+
max_dist2 = dist2;
771+
max_index = k;
772+
}
773+
}
774+
if (max_dist2 <= epsilon * epsilon) {
775+
continue;
776+
}
777+
q.push({i, max_index});
778+
q.push({max_index, j});
779+
}
780+
}
781+
782+
inline Eigen::VectorXi douglas_simplify_mask(const RowVectors &coords,
783+
double epsilon, //
784+
bool is_wgs84 = false, //
785+
bool recursive = true)
748786
{
749787
if (is_wgs84) {
750-
return douglas_simplify_mask(lla2enu(coords), epsilon, !is_wgs84);
788+
return douglas_simplify_mask(lla2enu(coords), epsilon, //
789+
false, recursive);
751790
}
752791
Eigen::VectorXi mask(coords.rows());
753792
mask.setZero();
754-
douglas_simplify(coords, mask, 0, mask.size() - 1, epsilon);
793+
if (recursive) {
794+
douglas_simplify(coords, mask, 0, mask.size() - 1, epsilon);
795+
} else {
796+
douglas_simplify_iter(coords, mask, epsilon);
797+
}
755798
return mask;
756799
}
757800

758-
inline Eigen::VectorXi
759-
douglas_simplify_indexes(const Eigen::Ref<const RowVectors> &coords,
760-
double epsilon, bool is_wgs84 = false)
801+
inline Eigen::VectorXi douglas_simplify_indexes(const RowVectors &coords,
802+
double epsilon, //
803+
bool is_wgs84 = false, //
804+
bool recursive = true)
761805
{
762-
return mask2indexes(douglas_simplify_mask(coords, epsilon, is_wgs84));
806+
return mask2indexes(
807+
douglas_simplify_mask(coords, epsilon, is_wgs84, recursive));
763808
}
764809

765-
inline RowVectors douglas_simplify(const Eigen::Ref<const RowVectors> &coords,
766-
double epsilon, bool is_wgs84 = false)
810+
inline RowVectors douglas_simplify(const RowVectors &coords,
811+
double epsilon, //
812+
bool is_wgs84 = false, //
813+
bool recursive = true)
814+
{
815+
return select_by_mask(
816+
coords, //
817+
douglas_simplify_mask(coords, epsilon, is_wgs84, recursive));
818+
}
819+
820+
// Nx2
821+
inline Eigen::VectorXi
822+
douglas_simplify_mask(const Eigen::Ref<const RowVectorsNx2> &coords,
823+
double epsilon, //
824+
bool is_wgs84 = false, //
825+
bool recursive = true)
826+
{
827+
return douglas_simplify_mask(to_Nx3(coords), epsilon, is_wgs84, recursive);
828+
}
829+
inline Eigen::VectorXi
830+
douglas_simplify_indexes(const Eigen::Ref<const RowVectorsNx2> &coords,
831+
double epsilon, //
832+
bool is_wgs84 = false, //
833+
bool recursive = true)
834+
{
835+
return douglas_simplify_indexes(to_Nx3(coords), epsilon, is_wgs84,
836+
recursive);
837+
}
838+
inline RowVectorsNx2
839+
douglas_simplify(const Eigen::Ref<const RowVectorsNx2> &coords,
840+
double epsilon, //
841+
bool is_wgs84 = false, //
842+
bool recursive = true)
767843
{
768-
return select_by_mask(coords,
769-
douglas_simplify_mask(coords, epsilon, is_wgs84));
844+
RowVectorsNx2 ret =
845+
douglas_simplify(to_Nx3(coords), epsilon, is_wgs84, recursive)
846+
.leftCols(2);
847+
return ret;
770848
}
771849

772850
} // namespace cubao

src/pybind11_polyline_ruler.hpp

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ CUBAO_INLINE void bind_polyline_ruler(py::module &m)
9393
py::overload_cast<int, double>(&PolylineRuler::range, py::const_),
9494
py::kw_only(), "segment_index"_a, "t"_a)
9595
//
96+
.def("segment_index", &PolylineRuler::segment_index, "range"_a)
97+
.def("segment_index_t", &PolylineRuler::segment_index_t, "range"_a)
98+
//
9699
.def("length", &PolylineRuler::length)
97100
//
98101
.def_static(
@@ -103,17 +106,19 @@ CUBAO_INLINE void bind_polyline_ruler(py::module &m)
103106
.def("dirs", py::overload_cast<>(&PolylineRuler::dirs, py::const_),
104107
rvp::reference_internal)
105108
//
109+
.def("dir", py::overload_cast<int>(&PolylineRuler::dir, py::const_),
110+
py::kw_only(), "point_index"_a)
106111
.def("dir",
107112
py::overload_cast<double, bool>(&PolylineRuler::dir, py::const_),
108-
"range"_a, py::kw_only(), "smooth_joint"_a = true)
113+
py::kw_only(), "range"_a, "smooth_joint"_a = true)
109114
.def("extended_along", &PolylineRuler::extended_along, "range"_a)
110115
.def("at", py::overload_cast<double>(&PolylineRuler::at, py::const_),
111-
"range"_a)
116+
py::kw_only(), "range"_a)
112117
.def("at", py::overload_cast<int>(&PolylineRuler::at, py::const_),
113-
"segment_index"_a)
118+
py::kw_only(), "segment_index"_a)
114119
.def("at",
115120
py::overload_cast<int, double>(&PolylineRuler::at, py::const_),
116-
"segment_index"_a, py::kw_only(), "t"_a)
121+
py::kw_only(), "segment_index"_a, "t"_a)
117122
.def("arrow", &PolylineRuler::arrow, "range"_a, //
118123
py::kw_only(), "smooth_joint"_a = true)
119124
.def("arrows",
@@ -201,5 +206,47 @@ CUBAO_INLINE void bind_polyline_ruler(py::module &m)
201206
"A"_a, "B"_a, py::kw_only(), "t"_a, "is_wgs84"_a = false)
202207
//
203208
;
209+
210+
m.def("douglas_simplify",
211+
py::overload_cast<const RowVectors &, double, bool,
212+
bool>(&douglas_simplify), //
213+
"coords"_a, "epsilon"_a, //
214+
py::kw_only(), //
215+
"is_wgs84"_a = false, //
216+
"recursive"_a = true);
217+
m.def(
218+
"douglas_simplify",
219+
py::overload_cast<const Eigen::Ref<const RowVectorsNx2> &, double, bool,
220+
bool>(&douglas_simplify), //
221+
"coords"_a, "epsilon"_a, //
222+
py::kw_only(), //
223+
"is_wgs84"_a = false, //
224+
"recursive"_a = true);
225+
m.def("douglas_simplify_mask",
226+
py::overload_cast<const RowVectors &, double, bool,
227+
bool>(&douglas_simplify_mask), //
228+
"coords"_a, "epsilon"_a, py::kw_only(), //
229+
"is_wgs84"_a = false, //
230+
"recursive"_a = true);
231+
m.def(
232+
"douglas_simplify_mask",
233+
py::overload_cast<const Eigen::Ref<const RowVectorsNx2> &, double, bool,
234+
bool>(&douglas_simplify_mask), //
235+
"coords"_a, "epsilon"_a, py::kw_only(), //
236+
"is_wgs84"_a = false, //
237+
"recursive"_a = true);
238+
m.def("douglas_simplify_indexes",
239+
py::overload_cast<const RowVectors &, double, bool,
240+
bool>(&douglas_simplify_indexes), //
241+
"coords"_a, "epsilon"_a, py::kw_only(), //
242+
"is_wgs84"_a = false, //
243+
"recursive"_a = true);
244+
m.def(
245+
"douglas_simplify_indexes",
246+
py::overload_cast<const Eigen::Ref<const RowVectorsNx2> &, double, bool,
247+
bool>(&douglas_simplify_indexes), //
248+
"coords"_a, "epsilon"_a, py::kw_only(), //
249+
"is_wgs84"_a = false, //
250+
"recursive"_a = true);
204251
}
205252
} // namespace cubao

0 commit comments

Comments
 (0)