From dd7cfeec8f24b395448a7918762c421257f75d18 Mon Sep 17 00:00:00 2001 From: TANG ZhiXiong Date: Sat, 11 Nov 2023 01:17:03 +0800 Subject: [PATCH] Integrate PackedRTree (rbush) (#24) * update headers * update headers * add planet * add tree * crop features * query * test query * update to 0.1.7 * fix index * bump flake: https://github.com/PyCQA/flake8/issues/1885 * fix lint --------- Co-authored-by: TANG ZHIXIONG --- .gitignore | 2 + .pre-commit-config.yaml | 3 +- .vscode/settings.json | 9 +- data/suzhoubeizhan.pbf | Bin 0 -> 169283 bytes data/suzhoubeizhan_crossover.json | 79 +++++++++++++ docs/about/release-notes.md | 4 + headers | 2 +- setup.py | 2 +- src/geobuf/geojson_cropping.hpp | 29 ++++- src/geobuf/planet.hpp | 186 ++++++++++++++++++++++++++++++ src/main.cpp | 20 ++++ tests/test_geobuf.py | 26 ++++- 12 files changed, 354 insertions(+), 8 deletions(-) create mode 100644 data/suzhoubeizhan.pbf create mode 100644 data/suzhoubeizhan_crossover.json create mode 100644 src/geobuf/planet.hpp diff --git a/.gitignore b/.gitignore index c4d726c..55226fe 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ tests/rapidjson.png.json __pycache__ benchmarks/*.json benchmarks/*.pbf* +# https://github.com/cubao/nano-fmm/blob/master/data/Makefile +data/suzhoubeizhan.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 432b377..b906381 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,6 +45,7 @@ repos: rev: 5.11.5 hooks: - id: isort + args: [--profile, black] # Upgrade older Python syntax - repo: https://github.com/asottile/pyupgrade @@ -61,7 +62,7 @@ repos: exclude: ^(docs|Makefile|benchmarks/Makefile) - repo: https://github.com/PyCQA/flake8 - rev: 3.9.2 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: [flake8-bugbear] diff --git a/.vscode/settings.json b/.vscode/settings.json index 0c4997d..5497d00 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -93,7 +93,14 @@ "regex": "cpp", "future": "cpp", "__bits": "cpp", - "bit": "cpp" + "bit": "cpp", + "charconv": "cpp", + "concepts": "cpp", + "memory_resource": "cpp", + "ranges": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "stop_token": "cpp" }, "workbench.colorCustomizations": { "activityBar.background": "#143328", diff --git a/data/suzhoubeizhan.pbf b/data/suzhoubeizhan.pbf new file mode 100644 index 0000000000000000000000000000000000000000..b38185b030ff460287e6d80ea9f565f4e7ffc418 GIT binary patch literal 169283 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’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 literal 0 HcmV?d00001 diff --git a/data/suzhoubeizhan_crossover.json b/data/suzhoubeizhan_crossover.json new file mode 100644 index 0000000..f0853b7 --- /dev/null +++ b/data/suzhoubeizhan_crossover.json @@ -0,0 +1,79 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [ + 120.65771383441779, + 31.406929844034934 + ], + [ + 120.65685254868885, + 31.405354623300482 + ], + [ + 120.65945178597582, + 31.403989410609327 + ], + [ + 120.66031307170232, + 31.402597923391937 + ], + [ + 120.66214330387294, + 31.401980936609206 + ], + [ + 120.66508090340801, + 31.403634977144364 + ], + [ + 120.66558844678389, + 31.4051183379097 + ], + [ + 120.66348137277282, + 31.406772323151472 + ], + [ + 120.66488096208019, + 31.407730571105034 + ], + [ + 120.66429651819169, + 31.408557544349165 + ], + [ + 120.66354289318042, + 31.409581405887053 + ], + [ + 120.66086675538332, + 31.409030097216544 + ], + [ + 120.66140505896414, + 31.407336771760555 + ], + [ + 120.66147901958857, + 31.407062414261205 + ], + [ + 120.66108904538675, + 31.406620542422047 + ], + [ + 120.65915262176173, + 31.40651150879127 + ], + [ + 120.65771383441779, + 31.406929844034934 + ] + ] + ], + "type": "Polygon" + } +} diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md index 7d6e426..ba82d3e 100644 --- a/docs/about/release-notes.md +++ b/docs/about/release-notes.md @@ -10,6 +10,10 @@ To upgrade `pybind11-geobuf` to the latest version, use pip: pip install -U pybind11-geobuf ``` +## Version 0.1.7 (2023-11-11) + +* Integrate PackedRTree (rbush) + ## Version 0.1.6 (2023-07-02) * Crop geojson features by polygon (alpha release) diff --git a/headers b/headers index 64c2294..0c34001 160000 --- a/headers +++ b/headers @@ -1 +1 @@ -Subproject commit 64c2294d63e9e4d61f59e39fb31352cab7fc71c5 +Subproject commit 0c34001ac35ca9f89088ac176d1f1a739f69d124 diff --git a/setup.py b/setup.py index a4a39e9..a9c3d58 100644 --- a/setup.py +++ b/setup.py @@ -127,7 +127,7 @@ def build_extension(self, ext): # logic and declaration, and simpler if you include description/version in a file. setup( name="pybind11_geobuf", - version="0.1.6", + version="0.1.7", author="tzx", author_email="dvorak4tzx@gmail.com", url="https://geobuf-cpp.readthedocs.io", diff --git a/src/geobuf/geojson_cropping.hpp b/src/geobuf/geojson_cropping.hpp index 97524e8..34d0f81 100644 --- a/src/geobuf/geojson_cropping.hpp +++ b/src/geobuf/geojson_cropping.hpp @@ -20,6 +20,7 @@ namespace cubao { using RowVectors = Eigen::Matrix; +using RowVectorsNx2 = Eigen::Matrix; using BboxType = mapbox::geometry::box; inline BboxType row_vectors_to_bbox(const RowVectors &coords) @@ -30,7 +31,7 @@ inline BboxType row_vectors_to_bbox(const RowVectors &coords) auto bbox = BboxType({max_t, max_t, max_t}, {min_t, min_t, min_t}); auto &min = bbox.min; auto &max = bbox.max; - for (int i = 1, N = coords.rows(); i < N; ++i) { + for (int i = 0, N = coords.rows(); i < N; ++i) { double x = coords(i, 0); double y = coords(i, 1); double z = coords(i, 2); @@ -50,6 +51,30 @@ inline BboxType row_vectors_to_bbox(const RowVectors &coords) return bbox; } +inline BboxType +row_vectors_to_bbox(const Eigen::Ref &coords) +{ + using limits = std::numeric_limits; + double min_t = limits::has_infinity ? -limits::infinity() : limits::min(); + double max_t = limits::has_infinity ? limits::infinity() : limits::max(); + auto bbox = BboxType({max_t, max_t, 0.0}, {min_t, min_t, 0.0}); + auto &min = bbox.min; + auto &max = bbox.max; + for (int i = 0, N = coords.rows(); i < N; ++i) { + double x = coords(i, 0); + double y = coords(i, 1); + if (min.x > x) + min.x = x; + if (min.y > y) + min.y = y; + if (max.x < x) + max.x = x; + if (max.y < y) + max.y = y; + } + return bbox; +} + inline RowVectors bbox2row_vectors(const BboxType &bbox) { auto coords = RowVectors(5, 3); @@ -176,7 +201,7 @@ inline int geojson_cropping(const mapbox::geojson::feature &feature, double len2 = std::get<5>(k2) - std::get<2>(k2); return len1 < len2; }); - keys = {*itr}; + keys = {*itr}; // pick longest } for (auto &key : keys) { auto &coords = segs[key]; diff --git a/src/geobuf/planet.hpp b/src/geobuf/planet.hpp new file mode 100644 index 0000000..277b264 --- /dev/null +++ b/src/geobuf/planet.hpp @@ -0,0 +1,186 @@ +#ifndef CUBAO_PLANET_HPP +#define CUBAO_PLANET_HPP + +// https://github.com/microsoft/vscode-cpptools/issues/9692 +#if __INTELLISENSE__ +#undef __ARM_NEON +#undef __ARM_NEON__ +#endif + +#include "geojson_cropping.hpp" +#include "packedrtree.hpp" + +namespace cubao +{ +struct Planet +{ + using FeatureCollection = mapbox::geojson::feature_collection; + Planet() = default; + Planet(const FeatureCollection &features) { this->features(features); } + + const FeatureCollection &features() const { return features_; } + Planet &features(const FeatureCollection &features) + { + features_ = features; + rtree_.reset(); + return *this; + } + + void build() const { this->rtree(); } + + // TODO, query by style expression + Eigen::VectorXi query(const Eigen::Vector2d &min, + const Eigen::Vector2d &max) const + { + auto &tree = this->rtree(); + auto hits = tree.search(min[0], min[1], max[0], max[1]); + Eigen::VectorXi index(hits.size()); + for (int i = 0, N = hits.size(); i < N; ++i) { + index[i] = hits[i].offset; + } + return index; + } + FeatureCollection copy(const Eigen::VectorXi &index) const + { + auto fc = FeatureCollection(); + fc.reserve(index.size()); + for (int i = 0, N = index.size(); i < N; ++i) { + fc.push_back(features_[index[i]]); + } + return fc; + } + + FeatureCollection crop(const Eigen::Ref &polygon, + const std::string &clipping_mode = "longest", + bool strip_properties = false, + bool is_wgs84 = true) const + { + auto bbox = row_vectors_to_bbox(polygon); + auto hits = + this->query({bbox.min.x, bbox.min.y}, {bbox.max.x, bbox.max.y}); + auto fc = FeatureCollection(); + fc.reserve(hits.size()); + for (auto idx : hits) { + auto &feature = features_[idx]; + if (!feature.geometry.is() || + clipping_mode == "whole") { + // only check centroid + auto centroid = geometry_to_centroid(feature.geometry); + auto mask = point_in_polygon( + Eigen::Map(¢roid.x, 1, 2), + polygon); + if (mask[0]) { + fc.emplace_back( + feature.geometry, + strip_properties + ? mapbox::feature::property_map{{"index", idx}} + : feature.properties, + feature.id); + } + continue; + } + auto &line_string = + feature.geometry.get(); + auto polyline = Eigen::Map(&line_string[0].x, + line_string.size(), 3); + auto segs = polyline_in_polygon(polyline, polygon, is_wgs84); + if (segs.empty()) { + continue; + } + if (clipping_mode == "first") { + auto &coords = segs.begin()->second; + auto geom = mapbox::geojson::line_string(); + geom.resize(coords.rows()); + as_row_vectors(geom) = coords; + fc.emplace_back( + geom, + strip_properties + ? mapbox::feature::property_map{{"index", idx}} + : feature.properties, + feature.id); + continue; + } + // longest or all + std::vector keys; + keys.reserve(segs.size()); + for (auto &pair : segs) { + keys.push_back(pair.first); + } + if (clipping_mode == "longest") { // else assume all + auto itr = std::max_element( + keys.begin(), keys.end(), + [](const auto &k1, const auto &k2) { + double len1 = std::get<5>(k1) - std::get<2>(k1); + double len2 = std::get<5>(k2) - std::get<2>(k2); + return len1 < len2; + }); + keys = {*itr}; // pick longest + } + for (auto &key : keys) { + auto &coords = segs[key]; + auto geom = mapbox::geojson::line_string(); + geom.resize(coords.rows()); + as_row_vectors(geom) = coords; + fc.emplace_back( + geom, + strip_properties + ? mapbox::feature::property_map{{"index", idx}} + : feature.properties, + feature.id); + } + } + return fc; + } + + private: + FeatureCollection features_; + + mutable std::optional rtree_; + + template + static FlatGeobuf::NodeItem envelope_2d(G const &geometry, uint64_t index) + { + // mapbox/geometry/envelope.hpp + using limits = std::numeric_limits; + constexpr double min_t = + limits::has_infinity ? -limits::infinity() : limits::min(); + constexpr double max_t = + limits::has_infinity ? limits::infinity() : limits::max(); + double min_x = max_t; + double min_y = max_t; + double max_x = min_t; + double max_y = min_t; + mapbox::geometry::for_each_point( + geometry, [&](mapbox::geojson::point const &point) { + if (min_x > point.x) + min_x = point.x; + if (min_y > point.y) + min_y = point.y; + if (max_x < point.x) + max_x = point.x; + if (max_y < point.y) + max_y = point.y; + }); + return {min_x, min_y, max_x, max_y, index}; + } + + FlatGeobuf::PackedRTree &rtree() const + { + if (rtree_) { + return *rtree_; + } + auto nodes = std::vector{}; + nodes.reserve(features_.size()); + uint64_t index{0}; + for (auto &feature : features_) { + nodes.emplace_back(envelope_2d(feature.geometry, index++)); + } + auto extent = calcExtent(nodes); + hilbertSort(nodes, extent); + rtree_ = FlatGeobuf::PackedRTree(nodes, extent); + return *rtree_; + } +}; +} // namespace cubao + +#endif diff --git a/src/main.cpp b/src/main.cpp index c26c4b4..e148ae6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ #include #include "geobuf/geobuf.hpp" +#include "geobuf/planet.hpp" #include "geobuf/pybind11_helpers.hpp" #include @@ -256,6 +257,25 @@ PYBIND11_MODULE(_pybind11_geobuf, m) auto geojson = m.def_submodule("geojson"); cubao::bind_geojson(geojson); + using Planet = cubao::Planet; + py::class_(m, "Planet", py::module_local()) + .def(py::init<>()) + .def(py::init()) + .def("features", py::overload_cast<>(&Planet::features, py::const_), + rvp::reference_internal) + .def("features", + py::overload_cast( + &Planet::features)) + .def("build", &Planet::build) + .def("query", &Planet::query, "min"_a, "max"_a) + .def("copy", &Planet::copy) + .def("crop", &Planet::crop, "polygon"_a, py::kw_only(), + "clipping_mode"_a = "longest", // + "strip_properties"_a = false, // + "is_wgs84"_a = true) + // + ; + cubao::bind_rapidjson(m); auto tf = m.def_submodule("tf"); diff --git a/tests/test_geobuf.py b/tests/test_geobuf.py index 8990ddd..a231406 100644 --- a/tests/test_geobuf.py +++ b/tests/test_geobuf.py @@ -15,6 +15,7 @@ from pybind11_geobuf import ( # noqa Decoder, Encoder, + Planet, geojson, normalize_json, pbf_decode, @@ -1400,7 +1401,7 @@ def test_geojson_feature(): assert props["list"].is_array() for x in list(props["list"].as_array()): assert isinstance(x, geojson.value) - assert type(x) == geojson.value + assert type(x) is geojson.value with pytest.raises(RuntimeError) as excinfo: props["list"].as_object() assert "in get()" in repr(excinfo) @@ -1412,7 +1413,7 @@ def test_geojson_feature(): for k, v in props["dict"].as_object().items(): assert isinstance(k, str) assert isinstance(v, geojson.value) - assert type(x) == geojson.value + assert type(x) is geojson.value with pytest.raises(RuntimeError) as excinfo: props["dict"].as_array() assert "in get()" in repr(excinfo) @@ -1755,6 +1756,27 @@ def test_rapidjson_normalize_non_geojson(): ) +def test_query(): + path = f"{__pwd}/../data/suzhoubeizhan.pbf" + fc = geojson.FeatureCollection().load(path) + planet = Planet(fc) + hits = planet.query([120.64094, 31.41515], [120.64137, 31.41534]) + assert len(hits) == 4 + + path = f"{__pwd}/../data/suzhoubeizhan_crossover.json" + polygon = geojson.Feature().load(path).to_numpy() + + cropped1 = planet.crop(polygon[:, :2]) + cropped2 = planet.crop(polygon[:, :2], strip_properties=True) + # cropped1.dump('cropped1.json', indent=True) + # cropped2.dump('cropped2.json', indent=True) + assert len(cropped1) == len(cropped2) == 54 + assert len(list(cropped1[0].properties().keys())) == 6 + assert list(cropped2[0].properties().keys()) == ["index"] + assert cropped2[0].properties()["index"]() == 438 + assert fc[438] == cropped1[0] + + if __name__ == "__main__": np.set_printoptions(suppress=True) pwd = os.path.abspath(os.path.dirname(__file__))