Coverage Report

Created: 2025-06-13 06:29

/src/MapServer/src/flatgeobuf/packedrtree.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  FlatGeobuf
4
 * Purpose:  Packed RTree management
5
 * Author:   Björn Harrtell <bjorn at wololo dot org>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2018-2020, Björn Harrtell <bjorn at wololo dot org>
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a
11
 * copy of this software and associated documentation files (the "Software"),
12
 * to deal in the Software without restriction, including without limitation
13
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14
 * and/or sell copies of the Software, and to permit persons to whom the
15
 * Software is furnished to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included
18
 * in all copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
 * DEALINGS IN THE SOFTWARE.
27
 ****************************************************************************/
28
29
// NOTE: The upstream of this file is in https://github.com/bjornharrtell/flatgeobuf/tree/master/src/cpp
30
31
#ifndef FLATGEOBUF_PACKEDRTREE_H_
32
#define FLATGEOBUF_PACKEDRTREE_H_
33
34
#include <cmath>
35
#include <numeric>
36
37
#include "flatbuffers/flatbuffers.h"
38
39
namespace mapserver {
40
namespace FlatGeobuf {
41
42
struct NodeItem {
43
    double minX;
44
    double minY;
45
    double maxX;
46
    double maxY;
47
    uint64_t offset;
48
0
    double width() const { return maxX - minX; }
49
0
    double height() const { return maxY - minY; }
50
0
    static NodeItem sum(NodeItem a, const NodeItem &b) {
51
0
        a.expand(b);
52
0
        return a;
53
0
    }
54
    static NodeItem create(uint64_t offset = 0);
55
    const NodeItem &expand(const NodeItem &r);
56
    bool intersects(const NodeItem &r) const;
57
    std::vector<double> toVector();
58
};
59
60
struct Item {
61
    NodeItem nodeItem;
62
};
63
64
struct SearchResultItem {
65
    uint64_t offset;
66
    uint64_t index;
67
};
68
69
std::ostream& operator << (std::ostream& os, NodeItem const& value);
70
71
uint32_t hilbert(uint32_t x, uint32_t y);
72
uint32_t hilbert(const NodeItem &n, uint32_t hilbertMax, const double minX, const double minY, const double width, const double height);
73
void hilbertSort(std::vector<std::shared_ptr<Item>> &items);
74
void hilbertSort(std::vector<NodeItem> &items);
75
NodeItem calcExtent(const std::vector<std::shared_ptr<Item>> &items);
76
NodeItem calcExtent(const std::vector<NodeItem> &rects);
77
78
/**
79
 * Packed R-Tree
80
 * Based on https://github.com/mourner/flatbush
81
 */
82
class PackedRTree {
83
    NodeItem _extent;
84
    NodeItem *_nodeItems = nullptr;
85
    uint64_t _numItems;
86
    uint64_t _numNodes;
87
    uint16_t _nodeSize;
88
    std::vector<std::pair<uint64_t, uint64_t>> _levelBounds;
89
    void init(const uint16_t nodeSize);
90
    void generateNodes();
91
    void fromData(const void *data);
92
public:
93
0
    ~PackedRTree() {
94
0
        if (_nodeItems != nullptr)
95
0
            delete[] _nodeItems;
96
0
    }
97
    PackedRTree(const std::vector<std::shared_ptr<Item>> &items, const NodeItem &extent, const uint16_t nodeSize = 16);
98
    PackedRTree(const std::vector<NodeItem> &nodes, const NodeItem &extent, const uint16_t nodeSize = 16);
99
    PackedRTree(const void *data, const uint64_t numItems, const uint16_t nodeSize = 16);
100
    std::vector<SearchResultItem> search(double minX, double minY, double maxX, double maxY) const;
101
    static std::vector<SearchResultItem> streamSearch(
102
        const uint64_t numItems, const uint16_t nodeSize, const NodeItem &item,
103
        const std::function<void(uint8_t *, size_t, size_t)> &readNode);
104
    static std::vector<std::pair<uint64_t, uint64_t>> generateLevelBounds(const uint64_t numItems, const uint16_t nodeSize);
105
    uint64_t size() const;
106
    static uint64_t size(const uint64_t numItems, const uint16_t nodeSize = 16);
107
    NodeItem getExtent() const;
108
    void streamWrite(const std::function<void(uint8_t *, size_t)> &writeData);
109
};
110
111
} }
112
113
#endif