-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathreader.hpp
More file actions
101 lines (81 loc) · 3.45 KB
/
Copy pathreader.hpp
File metadata and controls
101 lines (81 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma once
#include <fcb/error.hpp>
#include <fcb/feature.hpp>
#include <fcb/header.hpp>
#include <fcb/packed_rtree.hpp>
#include <fcb/range_reader.hpp>
#include <fcb/stree.hpp>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
namespace fcb {
/// One hit from an index traversal.
struct SearchResultItem {
std::uint64_t offset; // relative to the features section
std::uint64_t index; // feature ordinal
};
/// How a FeatureIterator decides what to visit.
///
/// This is an explicit mode rather than "an empty offset list means scan
/// everything": an empty list is also the perfectly normal result of a
/// query that matched nothing, and conflating the two would silently turn
/// a zero-result query into a full scan.
enum class IterationMode {
SequentialScan, ///< walk the features section start to finish
OffsetList, ///< visit exactly the offsets supplied (possibly none)
};
/// Single-pass iterator over features. Not copyable.
class FeatureIterator {
public:
FeatureIterator(std::shared_ptr<RangeReader> reader, HeaderView header, IterationMode mode,
std::vector<SearchResultItem> hits);
FeatureIterator(const FeatureIterator&) = delete;
FeatureIterator& operator=(const FeatureIterator&) = delete;
FeatureIterator(FeatureIterator&&) = default;
FeatureIterator& operator=(FeatureIterator&&) = delete;
/// Advance. Returns false once iteration is complete.
/// Throws if the file is truncated before features_count features.
bool next();
const Feature& current() const { return current_; }
/// Total features the header claims, for progress reporting.
std::uint64_t features_count() const { return header_.info().features_count; }
private:
std::shared_ptr<RangeReader> reader_;
HeaderView header_;
IterationMode mode_;
std::vector<SearchResultItem> hits_;
Feature current_;
std::uint64_t cursor_ = 0; // absolute, for SequentialScan
std::size_t hit_index_ = 0; // for OffsetList
std::uint64_t produced_ = 0;
};
/// The library's entry point.
class FcbReader {
public:
static FcbReader open_file(const std::string& path);
static FcbReader open(std::shared_ptr<RangeReader> reader);
const HeaderView& header() const { return header_; }
/// Iterate every feature in stored (Hilbert) order.
FeatureIterator select_all();
/// Iterate features whose 2D bounding box intersects `query`.
/// The R-tree is 2D only, so any z filtering is the caller's job.
/// Returns an empty iterator when nothing matches -- which is distinct
/// from a sequential scan, hence IterationMode.
FeatureIterator select_bbox(const BBox& query);
/// Iterate features matching every condition (AND).
///
/// Fixed-width string keys are truncated to 50 or 100 bytes, so the index
/// yields CANDIDATES for those columns; by default each is verified
/// against the decoded, untruncated attribute before being returned.
/// That makes this stricter than the Rust reader, which returns the
/// false positives. Matching is existential: a feature matches if any of
/// its CityObjects satisfies the condition. Each feature is returned at
/// most once.
FeatureIterator select_attr(const AttrQuery& query, AttrQueryOptions opts = {});
private:
FcbReader(std::shared_ptr<RangeReader> reader, HeaderView header);
std::shared_ptr<RangeReader> reader_;
HeaderView header_;
};
} // namespace fcb