Skip to content

Commit 2a5c510

Browse files
for wgs84 coords in PolylineRuler, convert lla2enu only once (#18)
* update headers * update build script * update linux image * misc updates * add cheapRuler * init cheap ruler * more cheap ruler bindings, tests * better performance for wgs84 coords * more binding, should be faster * update docs * lint code * better * fix * update headers (synced) --------- Co-authored-by: TANG ZHIXIONG <zhixiong.tang@momenta.ai>
1 parent 9e0f6ad commit 2a5c510

File tree

11 files changed

+239
-39
lines changed

11 files changed

+239
-39
lines changed

Makefile

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
PROJECT_SOURCE_DIR ?= $(abspath ./)
2+
PROJECT_NAME ?= $(shell basename $(PROJECT_SOURCE_DIR))
3+
14
all:
25
@echo nothing special
36

@@ -23,7 +26,7 @@ docs_serve:
2326
mkdocs serve -a 0.0.0.0:8088
2427

2528
DOCKER_TAG_WINDOWS ?= ghcr.io/cubao/build-env-windows-x64:v0.0.1
26-
DOCKER_TAG_LINUX ?= ghcr.io/cubao/build-env-manylinux2014-x64:v0.0.1
29+
DOCKER_TAG_LINUX ?= ghcr.io/cubao/build-env-manylinux2014-x64:v0.0.3
2730
DOCKER_TAG_MACOS ?= ghcr.io/cubao/build-env-macos-arm64:v0.0.1
2831

2932
test_in_win:
@@ -33,6 +36,16 @@ test_in_mac:
3336
test_in_linux:
3437
docker run --rm -w `pwd` -v `pwd`:`pwd` -v `pwd`/build/linux:`pwd`/build -it $(DOCKER_TAG_LINUX) bash
3538

39+
DEV_CONTAINER_NAME ?= $(USER)_$(subst /,_,$(PROJECT_NAME)____$(PROJECT_SOURCE_DIR))
40+
DEV_CONTAINER_IMAG ?= $(DOCKER_TAG_LINUX)
41+
test_in_container:
42+
test_in_dev_container:
43+
docker ps | grep $(DEV_CONTAINER_NAME) \
44+
&& docker exec -it $(DEV_CONTAINER_NAME) bash \
45+
|| docker run --rm --name $(DEV_CONTAINER_NAME) \
46+
--network host --security-opt seccomp=unconfined \
47+
-v `pwd`:`pwd` -w `pwd` -it $(DEV_CONTAINER_IMAG) bash
48+
3649
PYTHON ?= python3
3750
python_install:
3851
$(PYTHON) setup.py install
@@ -62,11 +75,13 @@ python_build_py39:
6275
PYTHON=python conda run --no-capture-output -n py39 make python_build
6376
python_build_py310:
6477
PYTHON=python conda run --no-capture-output -n py310 make python_build
65-
python_build_all: python_build_py36 python_build_py37 python_build_py38 python_build_py39 python_build_py310
78+
python_build_py311:
79+
PYTHON=python conda run --no-capture-output -n py311 make python_build
80+
python_build_all: python_build_py36 python_build_py37 python_build_py38 python_build_py39 python_build_py310 python_build_py311
6681
python_build_all_in_linux:
67-
docker run --rm -w `pwd` -v `pwd`:`pwd` -v `pwd`/build/win:`pwd`/build -it $(DOCKER_TAG_LINUX) make python_build_all
82+
docker run --rm -w `pwd` -v `pwd`:`pwd` -v `pwd`/build/linux:`pwd`/build -it $(DOCKER_TAG_LINUX) make python_build_all
6883
make repair_wheels && rm -rf dist/*.whl && mv wheelhouse/*.whl dist && rm -rf wheelhouse
69-
python_build_all_in_macos: python_build_py38 python_build_py39 python_build_py310
84+
python_build_all_in_macos: python_build_py38 python_build_py39 python_build_py310 python_build_py311
7085
python_build_all_in_windows: python_build_all
7186

7287
repair_wheels:
@@ -82,14 +97,15 @@ tar.gz:
8297
tar -cvz --exclude .git -f ../polyline-ruler.tar.gz .
8398
ls -alh ../polyline-ruler.tar.gz
8499

85-
SYNC_OUTPUT_DIR := headers/include/cubao
100+
SYNC_OUTPUT_DIR ?= headers/include/cubao
86101
sync_headers:
87102
mkdir -p $(SYNC_OUTPUT_DIR)
88103
cp src/cheap_ruler.hpp $(SYNC_OUTPUT_DIR)
89104
cp src/crs_transform.hpp $(SYNC_OUTPUT_DIR)
90105
cp src/cubao_inline.hpp $(SYNC_OUTPUT_DIR)
91106
cp src/eigen_helpers.hpp $(SYNC_OUTPUT_DIR)
92107
cp src/polyline_ruler.hpp $(SYNC_OUTPUT_DIR)
108+
cp src/pybind11_cheap_ruler.hpp $(SYNC_OUTPUT_DIR)
93109
cp src/pybind11_crs_transform.hpp $(SYNC_OUTPUT_DIR)
94110
cp src/pybind11_polyline_ruler.hpp $(SYNC_OUTPUT_DIR)
95111

docs/about/release-notes.md

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

13+
## Version 0.0.5 (2023-06-23)
14+
15+
* Faster pointOnLine by lla2enu hard copy once
16+
1317
## Version 0.0.4 (2023-03-11)
1418

1519
* Misc updates

headers

Submodule headers updated 65 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.4",
125+
version="0.0.5",
126126
author="tzx",
127127
author_email="dvorak4tzx@gmail.com",
128128
url="https://polyline-ruler.readthedocs.io",

src/cheap_ruler.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,19 @@
1616
#include <Eigen/Core>
1717

1818
#include <cassert>
19-
#include <cmath>
2019
#include <cstdint>
2120
#include <limits>
2221
#include <array>
2322
#include <tuple>
2423
#include <utility>
2524
#include <vector>
2625

26+
#define _USE_MATH_DEFINES
27+
#include <cmath>
28+
#ifndef M_PI
29+
#define M_PI 3.14159265358979323846
30+
#endif
31+
2732
namespace cubao
2833
{
2934
using RowVectors = Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::RowMajor>;
@@ -41,14 +46,14 @@ using polygon = RowVectors;
4146
class CheapRuler
4247
{
4348

49+
public:
4450
// Values that define WGS84 ellipsoid model of the Earth
4551
static constexpr double RE = 6378.137; // equatorial radius
4652
static constexpr double FE = 1.0 / 298.257223563; // flattening
4753

4854
static constexpr double E2 = FE * (2 - FE);
4955
static constexpr double RAD = M_PI / 180.0;
5056

51-
public:
5257
enum Unit
5358
{
5459
Kilometers,
@@ -160,7 +165,7 @@ class CheapRuler
160165
//
161166
// Returns the bearing between two points in angles.
162167
// 0
163-
// 45 45
168+
// -45 45
164169
// -90 90
165170
// -135 135
166171
// 180
@@ -472,14 +477,15 @@ class CheapRuler
472477
return point(a[0] + dx * t, a[1] + dy * t, a[2] + dz * t);
473478
}
474479

475-
private:
476-
double ky;
477-
double kx;
478-
double kz;
479480
static double longDiff(double a, double b)
480481
{
481482
return std::remainder(a - b, 360);
482483
}
484+
485+
private:
486+
double ky;
487+
double kx;
488+
double kz;
483489
};
484490

485491
} // namespace cheap_ruler

src/crs_transform.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
#include <Eigen/Geometry>
1616
#include <optional>
1717

18+
#define _USE_MATH_DEFINES
19+
#include <cmath>
20+
#ifndef M_PI
21+
#define M_PI 3.14159265358979323846
22+
#endif
23+
1824
namespace cubao
1925
{
2026

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "pybind11_crs_transform.hpp"
2929
#include "pybind11_polyline_ruler.hpp"
30+
#include "pybind11_cheap_ruler.hpp"
3031

3132
#define STRINGIFY(x) #x
3233
#define MACRO_STRINGIFY(x) STRINGIFY(x)
@@ -53,6 +54,7 @@ PYBIND11_MODULE(polyline_ruler, m)
5354
cubao::bind_crs_transform(tf);
5455

5556
cubao::bind_polyline_ruler(m);
57+
cubao::bind_cheap_ruler(m);
5658

5759
#ifdef VERSION_INFO
5860
m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO);

src/polyline_ruler.hpp

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <optional>
1616
#include <queue>
1717

18-
#include "cheap_ruler.hpp"
1918
#include "crs_transform.hpp"
2019
#include "eigen_helpers.hpp"
2120

@@ -224,7 +223,7 @@ struct PolylineRuler
224223
: polyline_(polyline), //
225224
N_(polyline.rows()), //
226225
is_wgs84_(is_wgs84), //
227-
k_(is_wgs84 ? CheapRuler::k(polyline(0, 1)) //
226+
k_(is_wgs84 ? cheap_ruler_k(polyline(0, 1)) //
228227
: Eigen::Vector3d::Ones())
229228
{
230229
}
@@ -244,6 +243,7 @@ struct PolylineRuler
244243
// cache
245244
mutable std::optional<Eigen::VectorXd> ranges_;
246245
mutable std::optional<RowVectors> dirs_;
246+
mutable std::optional<RowVectors> enus_; // only when is_wgs84==true
247247

248248
public:
249249
const RowVectors &polyline() const { return polyline_; }
@@ -370,6 +370,49 @@ struct PolylineRuler
370370
return *dirs_;
371371
}
372372

373+
private:
374+
const RowVectors &enus() const
375+
{
376+
assert(is_wgs84_);
377+
if (!enus_) {
378+
enus_ = __lla2enu(polyline_);
379+
}
380+
return *enus_;
381+
}
382+
Eigen::Vector3d __enu2lla(const Eigen::Vector3d &enu) const
383+
{
384+
return (enu.array() / k_.array()) + Eigen::Array3d(polyline_(0, 0),
385+
polyline_(0, 1),
386+
polyline_(0, 2));
387+
}
388+
Eigen::Vector3d __lla2enu(const Eigen::Vector3d &lla) const
389+
{
390+
return k_.array() * (lla - Eigen::Vector3d(polyline_(0, 0), //
391+
polyline_(0, 1), //
392+
polyline_(0, 2)))
393+
.array();
394+
}
395+
396+
RowVectors __enu2lla(const RowVectors &enus) const
397+
{
398+
RowVectors llas = enus;
399+
for (int i = 0; i < 3; ++i) {
400+
llas.col(i).array() /= k_[i];
401+
llas.col(i).array() += polyline_(0, i);
402+
}
403+
return llas;
404+
}
405+
RowVectors __lla2enu(const RowVectors &llas) const
406+
{
407+
RowVectors enus = llas;
408+
for (int i = 0; i < 3; ++i) {
409+
enus.col(i).array() -= polyline_(0, i);
410+
enus.col(i).array() *= k_[i];
411+
}
412+
return enus;
413+
}
414+
415+
public:
373416
Eigen::Vector3d dir(int pt_index) const
374417
{
375418
return dirs().row(std::min(pt_index, N_ - 2));
@@ -395,8 +438,7 @@ struct PolylineRuler
395438
Eigen::Vector3d extended_along(double range) const
396439
{
397440
auto [i, t] = segment_index_t(range);
398-
return interpolate(polyline_.row(i), polyline_.row(i + 1), t,
399-
is_wgs84_);
441+
return interpolate(polyline_.row(i), polyline_.row(i + 1), t);
400442
}
401443

402444
Eigen::Vector3d at(double range) const { return extended_along(range); }
@@ -405,7 +447,7 @@ struct PolylineRuler
405447
{
406448
return interpolate(polyline_.row(seg_idx), //
407449
polyline_.row(seg_idx + 1), //
408-
t, is_wgs84_);
450+
t);
409451
}
410452

411453
std::pair<Eigen::Vector3d, Eigen::Vector3d> arrow(int seg_idx,
@@ -432,7 +474,8 @@ struct PolylineRuler
432474
xyzs.row(i) = arrow.first;
433475
dirs.row(i) = arrow.second;
434476
}
435-
return std::make_tuple(std::move(ranges), std::move(xyzs),
477+
return std::make_tuple(std::move(ranges), //
478+
std::move(xyzs), //
436479
std::move(dirs));
437480
}
438481

@@ -536,7 +579,8 @@ struct PolylineRuler
536579
}
537580
Eigen::Vector3d along(double dist) const
538581
{
539-
return along(polyline_, dist, is_wgs84_);
582+
return is_wgs84_ ? __enu2lla(along(enus(), dist))
583+
: along(polyline_, dist);
540584
}
541585

542586
static double pointToSegmentDistance(const Eigen::Vector3d &p,
@@ -609,7 +653,11 @@ struct PolylineRuler
609653
std::tuple<Eigen::Vector3d, int, double>
610654
pointOnLine(const Eigen::Vector3d &p) const
611655
{
612-
return pointOnLine(polyline_, p, is_wgs84_);
656+
if (!is_wgs84_) {
657+
return pointOnLine(polyline_, p);
658+
}
659+
auto [enu, i, t] = pointOnLine(enus(), __lla2enu(p));
660+
return std::make_tuple(__enu2lla(enu), i, t);
613661
}
614662

615663
static RowVectors lineSlice(const Eigen::Vector3d &start,
@@ -668,7 +716,10 @@ struct PolylineRuler
668716
RowVectors lineSlice(const Eigen::Vector3d &start,
669717
const Eigen::Vector3d &stop) const
670718
{
671-
return lineSlice(start, stop, polyline_, is_wgs84_);
719+
if (!is_wgs84_) {
720+
return lineSlice(start, stop, polyline_);
721+
}
722+
return __enu2lla(lineSlice(__lla2enu(start), __lla2enu(stop), enus()));
672723
}
673724

674725
static RowVectors lineSliceAlong(double start, double stop,
@@ -709,23 +760,15 @@ struct PolylineRuler
709760
}
710761
RowVectors lineSliceAlong(double start, double stop) const
711762
{
712-
return lineSliceAlong(start, stop, polyline_, is_wgs84_);
763+
if (!is_wgs84_) {
764+
return lineSliceAlong(start, stop, polyline_);
765+
}
766+
return __enu2lla(lineSliceAlong(start, stop, enus()));
713767
}
714768

715769
static Eigen::Vector3d interpolate(const Eigen::Vector3d &a,
716-
const Eigen::Vector3d &b, double t,
717-
bool is_wgs84 = false)
770+
const Eigen::Vector3d &b, double t)
718771
{
719-
if (is_wgs84) {
720-
RowVectors llas(2, 3);
721-
llas.row(0) = a;
722-
llas.row(1) = b;
723-
auto enus = lla2enu(llas);
724-
return enu2lla(interpolate(enus.row(0), enus.row(1), t, !is_wgs84)
725-
.transpose(),
726-
llas.row(0))
727-
.row(0);
728-
}
729772
return a + (b - a) * t;
730773
}
731774
};
@@ -755,8 +798,9 @@ inline void douglas_simplify(const Eigen::Ref<const RowVectors> &coords,
755798
douglas_simplify(coords, to_keep, max_index, j, epsilon);
756799
}
757800

758-
void douglas_simplify_iter(const Eigen::Ref<const RowVectors> &coords,
759-
Eigen::VectorXi &to_keep, const double epsilon)
801+
inline void douglas_simplify_iter(const Eigen::Ref<const RowVectors> &coords,
802+
Eigen::VectorXi &to_keep,
803+
const double epsilon)
760804
{
761805
std::queue<std::pair<int, int>> q;
762806
q.push({0, to_keep.size() - 1});

0 commit comments

Comments
 (0)