librtree 0.9.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +80 -0
- data/COPYING +21 -0
- data/README.md +87 -0
- data/ext/rtree/extconf.rb +37 -19
- data/ext/rtree/lib/README.md +9 -0
- data/ext/rtree/lib/bindex.c +157 -0
- data/ext/rtree/lib/bindex.h +31 -0
- data/ext/rtree/lib/bounds.h +21 -0
- data/ext/rtree/lib/branch.c +51 -0
- data/ext/rtree/lib/branches.c +17 -0
- data/ext/rtree/lib/bsrt.c +704 -0
- data/ext/rtree/lib/bsrt.h +16 -0
- data/ext/rtree/lib/constants.h +19 -0
- data/ext/rtree/lib/csv.c +81 -0
- data/ext/rtree/lib/csv.h +16 -0
- data/ext/rtree/lib/endianness.h +83 -0
- data/ext/rtree/lib/error.c +47 -0
- data/ext/rtree/lib/json.c +491 -0
- data/ext/rtree/lib/json.h +16 -0
- data/ext/rtree/lib/mk/Hdr.mk +3 -0
- data/ext/rtree/lib/mk/MakeDepend +25 -0
- data/ext/rtree/lib/mk/Obj.mk +3 -0
- data/ext/rtree/lib/node.c +736 -0
- data/ext/rtree/lib/package.c +11 -0
- data/ext/rtree/lib/page.c +47 -0
- data/ext/rtree/lib/page.h +13 -0
- data/ext/rtree/lib/postscript.c +543 -0
- data/ext/rtree/lib/rect.c +139 -0
- data/ext/rtree/lib/rectf.c +219 -0
- data/ext/rtree/lib/rtree/branch.h +105 -0
- data/ext/rtree/lib/rtree/branches.h +38 -0
- data/ext/rtree/lib/rtree/error.h +42 -0
- data/ext/rtree/lib/rtree/extent.h +20 -0
- data/ext/rtree/lib/rtree/node.h +96 -0
- data/ext/rtree/lib/rtree/package.h +14 -0
- data/ext/rtree/lib/rtree/postscript.h +66 -0
- data/ext/rtree/lib/rtree/rect.h +38 -0
- data/ext/rtree/lib/rtree/rectf.h +34 -0
- data/ext/rtree/lib/rtree/search.h +27 -0
- data/ext/rtree/lib/rtree/state.h +113 -0
- data/ext/rtree/lib/rtree/types.h +14 -0
- data/ext/rtree/lib/rtree-base.c +197 -0
- data/ext/rtree/lib/rtree.h +62 -0
- data/ext/rtree/lib/search.c +54 -0
- data/ext/rtree/lib/split.c +710 -0
- data/ext/rtree/lib/split.h +15 -0
- data/ext/rtree/lib/spvol.c +48 -0
- data/ext/rtree/lib/spvol.h +13 -0
- data/ext/rtree/lib/state.c +169 -0
- data/ext/rtree/rtree.c +11 -0
- data/lib/rtree.rb +4 -4
- metadata +65 -3
@@ -0,0 +1,139 @@
|
|
1
|
+
#ifdef HAVE_CONFIG_H
|
2
|
+
#include "config.h"
|
3
|
+
#endif
|
4
|
+
|
5
|
+
#include "rtree/rect.h"
|
6
|
+
#include "rtree/error.h"
|
7
|
+
|
8
|
+
#ifdef HAVE_TGMATH_H
|
9
|
+
#include <tgmath.h>
|
10
|
+
#else
|
11
|
+
#include <math.h>
|
12
|
+
#endif
|
13
|
+
|
14
|
+
#ifdef HAVE_FEATURES_H
|
15
|
+
#include <features.h>
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#include <string.h>
|
19
|
+
#include <errno.h>
|
20
|
+
|
21
|
+
int rect_init(const state_t *state, rtree_coord_t *rect)
|
22
|
+
{
|
23
|
+
if (rect == NULL)
|
24
|
+
return RTREE_ERR_INVAL;
|
25
|
+
|
26
|
+
#ifdef __STDC_IEC_559__
|
27
|
+
|
28
|
+
memset(rect, 0, state_rect_size(state));
|
29
|
+
|
30
|
+
#else
|
31
|
+
|
32
|
+
const size_t dims = state_dims(state);
|
33
|
+
|
34
|
+
for (size_t i = 0 ; i < 2 * dims ; i++)
|
35
|
+
rect[i] = 0;
|
36
|
+
|
37
|
+
#endif
|
38
|
+
|
39
|
+
return RTREE_OK;
|
40
|
+
}
|
41
|
+
|
42
|
+
bool rect_intersect(const state_t *state,
|
43
|
+
const rtree_coord_t *a, const rtree_coord_t *b)
|
44
|
+
{
|
45
|
+
const size_t dims = state_dims(state);
|
46
|
+
|
47
|
+
for (size_t dim = 0 ; dim < dims ; dim++)
|
48
|
+
{
|
49
|
+
const size_t
|
50
|
+
low = dim,
|
51
|
+
high = dim + dims;
|
52
|
+
|
53
|
+
if ((a[high] < b[low]) || (a[low] > b[high]))
|
54
|
+
return false;
|
55
|
+
}
|
56
|
+
|
57
|
+
return true;
|
58
|
+
}
|
59
|
+
|
60
|
+
rtree_coord_t rect_volume(const state_t *state, const rtree_coord_t *rect)
|
61
|
+
{
|
62
|
+
const size_t dims = state_dims(state);
|
63
|
+
rtree_coord_t v = rect[dims] - rect[0];
|
64
|
+
|
65
|
+
for (size_t i = 1 ; i < dims ; i++)
|
66
|
+
v *= (rect[dims + i] - rect[i]);
|
67
|
+
|
68
|
+
return v;
|
69
|
+
}
|
70
|
+
|
71
|
+
rtree_coord_t rect_spherical_volume(const state_t *state,
|
72
|
+
const rtree_coord_t *rect)
|
73
|
+
{
|
74
|
+
return state_rsv(state, rect);
|
75
|
+
}
|
76
|
+
|
77
|
+
void rect_copy(const state_t *state, const rtree_coord_t *src,
|
78
|
+
rtree_coord_t *dest)
|
79
|
+
{
|
80
|
+
memcpy(dest, src, state_rect_size(state));
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
void rect_combine(const state_t *state,
|
85
|
+
const rtree_coord_t *restrict rect0,
|
86
|
+
const rtree_coord_t *restrict rect1,
|
87
|
+
rtree_coord_t *restrict rect2)
|
88
|
+
{
|
89
|
+
state_rc(state, rect0, rect1, rect2);
|
90
|
+
}
|
91
|
+
|
92
|
+
void rect_merge(const state_t *state,
|
93
|
+
const rtree_coord_t *rect0,
|
94
|
+
rtree_coord_t *rect1)
|
95
|
+
{
|
96
|
+
state_rc(state, rect0, rect1, rect1);
|
97
|
+
}
|
98
|
+
|
99
|
+
bool rect_identical(const state_t *state,
|
100
|
+
const rtree_coord_t *rect0,
|
101
|
+
const rtree_coord_t *rect1)
|
102
|
+
{
|
103
|
+
for (size_t i = 0 ; i < 2 * state_dims(state) ; i++)
|
104
|
+
if (rect0[i] != rect1[i]) return false;
|
105
|
+
return true;
|
106
|
+
}
|
107
|
+
|
108
|
+
/*
|
109
|
+
Allocates n rectangles (as rtree_coord_t*) and assigns them to the
|
110
|
+
elements of the array rects, which should already be allocated (so
|
111
|
+
one would pass 'array' declared as rtree_coord_t *array[2], for
|
112
|
+
example).
|
113
|
+
*/
|
114
|
+
|
115
|
+
int rects_alloc(const state_t *state, size_t n, rtree_coord_t **rects)
|
116
|
+
{
|
117
|
+
const size_t
|
118
|
+
dims = state_dims(state),
|
119
|
+
rect_size = state_rect_size(state);
|
120
|
+
rtree_coord_t *floats;
|
121
|
+
|
122
|
+
if ((floats = calloc(n, rect_size)) == NULL)
|
123
|
+
return RTREE_ERR_NOMEM;
|
124
|
+
|
125
|
+
*rects = floats;
|
126
|
+
|
127
|
+
for (size_t i = 1 ; i < n ; i++)
|
128
|
+
rects[i] = floats + 2 * i * dims;
|
129
|
+
|
130
|
+
return RTREE_OK;
|
131
|
+
}
|
132
|
+
|
133
|
+
void rects_free(size_t n, rtree_coord_t **rects)
|
134
|
+
{
|
135
|
+
free(*rects);
|
136
|
+
|
137
|
+
for (size_t i = 0 ; i < n ; i++)
|
138
|
+
rects[i] = NULL;
|
139
|
+
}
|
@@ -0,0 +1,219 @@
|
|
1
|
+
#ifdef HAVE_CONFIG_H
|
2
|
+
#include "config.h"
|
3
|
+
#endif
|
4
|
+
|
5
|
+
#include "rtree/rectf.h"
|
6
|
+
|
7
|
+
#ifdef HAVE_TGMATH_H
|
8
|
+
#include <tgmath.h>
|
9
|
+
#else
|
10
|
+
#include <math.h>
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#ifdef HAVE_XMMINTRIN_H
|
14
|
+
#include <xmmintrin.h>
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#ifdef HAVE_IMMINTRIN_H
|
18
|
+
#include <immintrin.h>
|
19
|
+
#endif
|
20
|
+
|
21
|
+
/*
|
22
|
+
rect_spherical_volume has some simplifications for small dimensions
|
23
|
+
(one need not call pow(), for example), and it gets called a lot so
|
24
|
+
worth selecting which to use just the once.
|
25
|
+
*/
|
26
|
+
|
27
|
+
#pragma GCC diagnostic push
|
28
|
+
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
29
|
+
|
30
|
+
rtree_coord_t rectf_rsv1(size_t dims, const rtree_coord_t *rect)
|
31
|
+
{
|
32
|
+
return 0.5 * fabs(rect[1] - rect[0]);
|
33
|
+
}
|
34
|
+
|
35
|
+
rtree_coord_t rectf_rsv2(size_t dims, const rtree_coord_t *rect)
|
36
|
+
{
|
37
|
+
rtree_coord_t
|
38
|
+
hx1 = rect[2] - rect[0],
|
39
|
+
hx2 = rect[3] - rect[1],
|
40
|
+
r2 = hx1 * hx1 + hx2 * hx2;
|
41
|
+
|
42
|
+
return 0.25 * r2;
|
43
|
+
}
|
44
|
+
|
45
|
+
#pragma GCC diagnostic pop
|
46
|
+
|
47
|
+
rtree_coord_t rectf_rsvd(size_t dims, const rtree_coord_t *rect)
|
48
|
+
{
|
49
|
+
rtree_coord_t
|
50
|
+
hx = rect[dims] - rect[0],
|
51
|
+
r2 = hx * hx;
|
52
|
+
|
53
|
+
for (size_t i = 1 ; i < dims ; i++)
|
54
|
+
{
|
55
|
+
hx = rect[i + dims] - rect[i];
|
56
|
+
r2 += hx * hx;
|
57
|
+
}
|
58
|
+
|
59
|
+
return pow(0.25 * r2, 0.5 * dims);
|
60
|
+
}
|
61
|
+
|
62
|
+
rectf_rsv_t* rectf_spherical_volume(size_t dims)
|
63
|
+
{
|
64
|
+
switch (dims)
|
65
|
+
{
|
66
|
+
case 1:
|
67
|
+
return rectf_rsv1;
|
68
|
+
case 2:
|
69
|
+
return rectf_rsv2;
|
70
|
+
default:
|
71
|
+
return rectf_rsvd;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
/*
|
76
|
+
rect_combine is performance-critical, and we use the same trick
|
77
|
+
for cases where the entire rectangle fits in a wide register:
|
78
|
+
the 128-bit register (SSE2) in the dim-2 float case, the 256
|
79
|
+
register (AVX) in the dim-3, -4 float and dim-2 double case. for
|
80
|
+
the first, We XOR with the "sign-mask" { 0, 0, -0, -0 } to sign
|
81
|
+
change the last two values, then find the min, then XOR again.
|
82
|
+
The result is the min of the bottom two values, the max of the
|
83
|
+
top two.
|
84
|
+
|
85
|
+
The dim-4 float and dim-2 double cases are similar, the dim-3
|
86
|
+
float version is the trickiest since we need to load 6 floats
|
87
|
+
into an 8-float register, so we need a mask (which is an AVX
|
88
|
+
facility).
|
89
|
+
*/
|
90
|
+
|
91
|
+
void rectf_rcd(size_t dims,
|
92
|
+
const rtree_coord_t *rect0,
|
93
|
+
const rtree_coord_t *rect1,
|
94
|
+
rtree_coord_t *rect2)
|
95
|
+
{
|
96
|
+
for (size_t i = 0 ; i < dims ; i++)
|
97
|
+
{
|
98
|
+
const size_t j = i + dims;
|
99
|
+
const rtree_coord_t
|
100
|
+
x0 = rect0[i], x1 = rect1[i],
|
101
|
+
y0 = rect0[j], y1 = rect1[j];
|
102
|
+
|
103
|
+
rect2[i] = fmin(x0, x1);
|
104
|
+
rect2[j] = fmax(y0, y1);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
#pragma GCC diagnostic push
|
109
|
+
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
110
|
+
|
111
|
+
#if SIZEOF_RTREE_COORD_T == 4
|
112
|
+
|
113
|
+
#ifdef HAVE_SSE2
|
114
|
+
|
115
|
+
void rectf_rc2(size_t dims,
|
116
|
+
const rtree_coord_t *rect0,
|
117
|
+
const rtree_coord_t *rect1,
|
118
|
+
rtree_coord_t *rect2)
|
119
|
+
{
|
120
|
+
const __m128
|
121
|
+
sm = { 0.0f, 0.0f, -0.0f, -0.0f },
|
122
|
+
sr0 = _mm_loadu_ps(rect0),
|
123
|
+
sr1 = _mm_loadu_ps(rect1),
|
124
|
+
srmin = _mm_min_ps(_mm_xor_ps(sm, sr0), _mm_xor_ps(sm, sr1)),
|
125
|
+
res = _mm_xor_ps(sm, srmin);
|
126
|
+
|
127
|
+
_mm_storeu_ps(rect2, res);
|
128
|
+
}
|
129
|
+
|
130
|
+
|
131
|
+
#endif
|
132
|
+
|
133
|
+
#ifdef HAVE_AVX
|
134
|
+
|
135
|
+
void rectf_rc3(size_t dims,
|
136
|
+
const rtree_coord_t *rect0,
|
137
|
+
const rtree_coord_t *rect1,
|
138
|
+
rtree_coord_t *rect2)
|
139
|
+
{
|
140
|
+
const __m256i
|
141
|
+
mask = _mm256_setr_epi32(-1, -1, -1, -1, -1, -1, 0, 0);
|
142
|
+
const __m256
|
143
|
+
sm = { 0.0f, 0.0f, 0.0f, -0.0f, -0.0f, -0.0f, 0.0f, 0.0f },
|
144
|
+
sr0 = _mm256_maskload_ps(rect0, mask),
|
145
|
+
sr1 = _mm256_maskload_ps(rect1, mask),
|
146
|
+
srmin = _mm256_min_ps(_mm256_xor_ps(sm, sr0), _mm256_xor_ps(sm, sr1)),
|
147
|
+
res = _mm256_xor_ps(sm, srmin);
|
148
|
+
|
149
|
+
_mm256_maskstore_ps(rect2, mask, res);
|
150
|
+
}
|
151
|
+
|
152
|
+
void rectf_rc4(size_t dims,
|
153
|
+
const rtree_coord_t *rect0,
|
154
|
+
const rtree_coord_t *rect1,
|
155
|
+
rtree_coord_t *rect2)
|
156
|
+
{
|
157
|
+
const __m256
|
158
|
+
sm = { 0.0f, 0.0f, 0.0f, 0.0f, -0.0f, -0.0f, -0.0f, -0.0f },
|
159
|
+
sr0 = _mm256_loadu_ps(rect0),
|
160
|
+
sr1 = _mm256_loadu_ps(rect1),
|
161
|
+
srmin = _mm256_min_ps(_mm256_xor_ps(sm, sr0), _mm256_xor_ps(sm, sr1)),
|
162
|
+
res = _mm256_xor_ps(sm, srmin);
|
163
|
+
|
164
|
+
_mm256_storeu_ps(rect2, res);
|
165
|
+
}
|
166
|
+
|
167
|
+
#endif
|
168
|
+
|
169
|
+
#elif SIZEOF_RTREE_COORD_T == 8
|
170
|
+
|
171
|
+
#ifdef HAVE_AVX
|
172
|
+
|
173
|
+
void rectf_rc2(size_t dims,
|
174
|
+
const rtree_coord_t *rect0,
|
175
|
+
const rtree_coord_t *rect1,
|
176
|
+
rtree_coord_t *rect2)
|
177
|
+
{
|
178
|
+
const __m256d
|
179
|
+
sm = { 0.0, 0.0, -0.0, -0.0 },
|
180
|
+
sr0 = _mm256_loadu_pd(rect0),
|
181
|
+
sr1 = _mm256_loadu_pd(rect1),
|
182
|
+
srmin = _mm256_min_pd(_mm256_xor_pd(sm, sr0), _mm256_xor_pd(sm, sr1)),
|
183
|
+
res = _mm256_xor_pd(sm, srmin);
|
184
|
+
|
185
|
+
_mm256_storeu_pd(rect2, res);
|
186
|
+
}
|
187
|
+
|
188
|
+
#endif
|
189
|
+
|
190
|
+
#else
|
191
|
+
#error "strange size for rtree_coord_t"
|
192
|
+
#endif
|
193
|
+
|
194
|
+
#pragma GCC diagnostic pop
|
195
|
+
|
196
|
+
rectf_rc_t* rectf_combine(size_t dims)
|
197
|
+
{
|
198
|
+
switch (dims)
|
199
|
+
{
|
200
|
+
|
201
|
+
#if SIZEOF_RTREE_COORD_T == 4
|
202
|
+
# ifdef HAVE_SSE2
|
203
|
+
case 2: return rectf_rc2;
|
204
|
+
# endif
|
205
|
+
# ifdef HAVE_AVX
|
206
|
+
case 3: return rectf_rc3;
|
207
|
+
case 4: return rectf_rc4;
|
208
|
+
# endif
|
209
|
+
#elif SIZEOF_RTREE_COORD_T == 8
|
210
|
+
# ifdef HAVE_AVX
|
211
|
+
case 2: return rectf_rc2;
|
212
|
+
# endif
|
213
|
+
#else
|
214
|
+
# error "strange size for rtree_coord_t"
|
215
|
+
#endif
|
216
|
+
|
217
|
+
default: return rectf_rcd;
|
218
|
+
}
|
219
|
+
}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
/*
|
2
|
+
rtree/branch.h
|
3
|
+
Copyright (c) J.J. Green 2019
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_BRANCH_H
|
7
|
+
#define RTREE_BRANCH_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#include <stdlib.h>
|
14
|
+
|
15
|
+
typedef struct branch_t branch_t;
|
16
|
+
|
17
|
+
#include <rtree/types.h>
|
18
|
+
#include <rtree/state.h>
|
19
|
+
#include <rtree/node.h>
|
20
|
+
#include <rtree/rect.h>
|
21
|
+
|
22
|
+
/*
|
23
|
+
The union is either a pointer to the child-node in the tree, or
|
24
|
+
if we are at level zero, the id payload. The latter may as well
|
25
|
+
be the size of a pointer.
|
26
|
+
|
27
|
+
The rect is big enough to hold 2 * dims floats, understood to be
|
28
|
+
[x0, y0, ..., x1, y1, ...] corresponding to the (hyper-)rectangle
|
29
|
+
x0 < x < x1, y0 < y < y1, ..., this must be at the end of the
|
30
|
+
struct (since variable).
|
31
|
+
|
32
|
+
For the sake of SSE, we would like the rect member to be 16-byte
|
33
|
+
aligned, and this could be done with
|
34
|
+
|
35
|
+
rtree_coord_t alignas(16) rect[];
|
36
|
+
|
37
|
+
but this would force the size of branch_t to be a multiple of 16,
|
38
|
+
so for the dimension 2 case with rtree_coord_t a float increases
|
39
|
+
branch size from 24 to 32 bytes, essentially increasing the size
|
40
|
+
of the tree by 20%. So we don't do that, and use non-aligned
|
41
|
+
variants for SSE load/save (apparently on recent CPUs the penalty
|
42
|
+
is pretty small).
|
43
|
+
*/
|
44
|
+
|
45
|
+
struct branch_t
|
46
|
+
{
|
47
|
+
union {
|
48
|
+
node_t *child;
|
49
|
+
rtree_id_t id;
|
50
|
+
};
|
51
|
+
rtree_coord_t rect[];
|
52
|
+
};
|
53
|
+
|
54
|
+
size_t branch_sizeof(size_t);
|
55
|
+
int branch_init(const state_t*, branch_t*);
|
56
|
+
branch_t* branch_copy(const state_t*, const branch_t*, branch_t*);
|
57
|
+
|
58
|
+
/* inline accessors */
|
59
|
+
|
60
|
+
inline void branch_set_child(branch_t *branch, node_t *child)
|
61
|
+
{
|
62
|
+
branch->child = child;
|
63
|
+
}
|
64
|
+
|
65
|
+
inline const node_t* branch_get_child(const branch_t *branch)
|
66
|
+
{
|
67
|
+
return branch->child;
|
68
|
+
}
|
69
|
+
|
70
|
+
inline node_t* branch_get_child_mutable(branch_t *branch)
|
71
|
+
{
|
72
|
+
return branch->child;
|
73
|
+
}
|
74
|
+
|
75
|
+
inline void branch_set_id(branch_t *branch, rtree_id_t id)
|
76
|
+
{
|
77
|
+
branch->id = id;
|
78
|
+
}
|
79
|
+
|
80
|
+
inline rtree_id_t branch_get_id(const branch_t *branch)
|
81
|
+
{
|
82
|
+
return branch->id;
|
83
|
+
}
|
84
|
+
|
85
|
+
inline void branch_set_rect(const state_t *state, branch_t *branch,
|
86
|
+
const rtree_coord_t *rect)
|
87
|
+
{
|
88
|
+
rect_copy(state, rect, branch->rect);
|
89
|
+
}
|
90
|
+
|
91
|
+
inline const rtree_coord_t* branch_get_rect(const branch_t *branch)
|
92
|
+
{
|
93
|
+
return branch->rect;
|
94
|
+
}
|
95
|
+
|
96
|
+
inline rtree_coord_t* branch_get_rect_mutable(branch_t *branch)
|
97
|
+
{
|
98
|
+
return branch->rect;
|
99
|
+
}
|
100
|
+
|
101
|
+
#ifdef __cplusplus
|
102
|
+
}
|
103
|
+
#endif
|
104
|
+
|
105
|
+
#endif
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/*
|
2
|
+
rtree/branches.h
|
3
|
+
Copyright (c) J.J. Green 2020
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_BRANCHES_H
|
7
|
+
#define RTREE_BRANCHES_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#include <stdlib.h>
|
14
|
+
#include <errno.h>
|
15
|
+
#include <string.h>
|
16
|
+
|
17
|
+
#include <rtree/state.h>
|
18
|
+
#include <rtree/branch.h>
|
19
|
+
#include <rtree/error.h>
|
20
|
+
|
21
|
+
inline branch_t* branches_get(const state_t *state, void *buffer, size_t i)
|
22
|
+
{
|
23
|
+
const size_t branch_size = state_branch_size(state);
|
24
|
+
char *bytes = (char*)buffer;
|
25
|
+
return (branch_t*)(bytes + i * branch_size);
|
26
|
+
}
|
27
|
+
|
28
|
+
inline void branches_set(const state_t *state, void *buffer, size_t i,
|
29
|
+
const branch_t *src)
|
30
|
+
{
|
31
|
+
memcpy(branches_get(state, buffer, i), src, state_branch_size(state));
|
32
|
+
}
|
33
|
+
|
34
|
+
#ifdef __cplusplus
|
35
|
+
}
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#endif
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/*
|
2
|
+
rtree/error.h
|
3
|
+
Copyright (c) J.J. Green 2020
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_ERROR_H
|
7
|
+
#define RTREE_ERROR_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#define RTREE_OK 0
|
14
|
+
#define RTREE_ERR_INVAL 1
|
15
|
+
#define RTREE_ERR_DOM 2
|
16
|
+
#define RTREE_ERR_NOMEM 3
|
17
|
+
#define RTREE_ERR_CSVPARSE 4
|
18
|
+
#define RTREE_ERR_NOCSV 5
|
19
|
+
#define RTREE_ERR_JANSSON 6
|
20
|
+
#define RTREE_ERR_NOJSON 7
|
21
|
+
#define RTREE_ERR_NOBSRT 8
|
22
|
+
#define RTREE_ERR_GETBRANCH 9
|
23
|
+
#define RTREE_ERR_GETCHILD 10
|
24
|
+
#define RTREE_ERR_NODECLONE 11
|
25
|
+
#define RTREE_ERR_PICKBRANCH 12
|
26
|
+
#define RTREE_ERR_ADDRECT 13
|
27
|
+
#define RTREE_ERR_NOSUCHSPLIT 14
|
28
|
+
#define RTREE_ERR_DIMS 15
|
29
|
+
#define RTREE_ERR_EMPTY 16
|
30
|
+
#define RTREE_ERR_BUFFER 17
|
31
|
+
#define RTREE_ERR_POSTSCRIPT 18
|
32
|
+
#define RTREE_ERR_USER 19
|
33
|
+
#define RTREE_ERR_FWRITE 20
|
34
|
+
#define RTREE_ERR_SPLIT 21
|
35
|
+
|
36
|
+
const char* strerror_rtree(int);
|
37
|
+
|
38
|
+
#ifdef __cplusplus
|
39
|
+
}
|
40
|
+
#endif
|
41
|
+
|
42
|
+
#endif
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
rtree/extent.h
|
3
|
+
Just an enum indicating a choice of axis (direction)
|
4
|
+
Copyright (c) J.J. Green 2020
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifndef RTREE_EXTENT_H
|
8
|
+
#define RTREE_EXTENT_H
|
9
|
+
|
10
|
+
#ifdef __cplusplus
|
11
|
+
extern "C" {
|
12
|
+
#endif
|
13
|
+
|
14
|
+
typedef enum { axis_width, axis_height } extent_axis_t;
|
15
|
+
|
16
|
+
#ifdef __cplusplus
|
17
|
+
}
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#endif
|
@@ -0,0 +1,96 @@
|
|
1
|
+
/*
|
2
|
+
rtree/node.h
|
3
|
+
Copyright (c) J.J. Green 2019
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_NODE_H
|
7
|
+
#define RTREE_NODE_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#if 0
|
12
|
+
}
|
13
|
+
#endif
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#include <stdint.h>
|
17
|
+
#include <stdbool.h>
|
18
|
+
#include <stddef.h>
|
19
|
+
|
20
|
+
typedef uint16_t node_level_t;
|
21
|
+
typedef uint16_t node_count_t;
|
22
|
+
typedef uint16_t node_height_t;
|
23
|
+
|
24
|
+
#define NODE_LEVEL_MAX UINT16_MAX
|
25
|
+
#define NODE_COUNT_MAX UINT16_MAX
|
26
|
+
|
27
|
+
typedef struct node_t node_t;
|
28
|
+
|
29
|
+
#include <rtree/types.h>
|
30
|
+
#include <rtree/state.h>
|
31
|
+
#include <rtree/branch.h>
|
32
|
+
|
33
|
+
struct node_t
|
34
|
+
{
|
35
|
+
node_level_t level;
|
36
|
+
node_count_t count;
|
37
|
+
char branches[];
|
38
|
+
};
|
39
|
+
|
40
|
+
typedef int (rtree_update_t)(rtree_id_t, rtree_coord_t*, void*);
|
41
|
+
typedef int (nbe_cb_t)(const state_t*, const branch_t*, void*);
|
42
|
+
|
43
|
+
int node_init(const state_t*, node_t*);
|
44
|
+
node_t* node_new(const state_t*);
|
45
|
+
void node_destroy(const state_t*, node_t*);
|
46
|
+
node_t* node_clone(const state_t*, const node_t*);
|
47
|
+
int node_branch_each(const state_t*, const node_t*, nbe_cb_t*, void*);
|
48
|
+
int node_branch_each_level(const state_t*, const node_t*, node_level_t,
|
49
|
+
nbe_cb_t*, void*);
|
50
|
+
size_t node_num_branch(size_t, size_t);
|
51
|
+
int node_detach_branch(const state_t*, node_t*, size_t);
|
52
|
+
node_t* node_add_branch(const state_t*, node_t*, branch_t*);
|
53
|
+
int node_envelope(const state_t*, const node_t*, rtree_coord_t*);
|
54
|
+
node_t* node_add_rect(const state_t*, rtree_id_t, rtree_coord_t*,
|
55
|
+
node_t*, node_level_t);
|
56
|
+
int node_update(const state_t*, const node_t*, rtree_update_t*, void*);
|
57
|
+
bool node_identical(const state_t*, const node_t*, const node_t*);
|
58
|
+
node_height_t node_height(const state_t*, const node_t*);
|
59
|
+
size_t node_bytes(const state_t*, const node_t*);
|
60
|
+
bool node_nonempty(const state_t*, const node_t*);
|
61
|
+
|
62
|
+
inline node_count_t node_count(const node_t *node)
|
63
|
+
{
|
64
|
+
return node->count;
|
65
|
+
}
|
66
|
+
|
67
|
+
inline void node_count_increment(node_t *node)
|
68
|
+
{
|
69
|
+
node->count++;
|
70
|
+
}
|
71
|
+
|
72
|
+
inline void node_count_decrement(node_t *node)
|
73
|
+
{
|
74
|
+
node->count--;
|
75
|
+
}
|
76
|
+
|
77
|
+
inline node_level_t node_level(const node_t *node)
|
78
|
+
{
|
79
|
+
return node->level;
|
80
|
+
}
|
81
|
+
|
82
|
+
inline void node_set_level(node_t *node, node_level_t level)
|
83
|
+
{
|
84
|
+
node->level = level;
|
85
|
+
}
|
86
|
+
|
87
|
+
inline void* node_get_branches(node_t *node)
|
88
|
+
{
|
89
|
+
return node->branches;
|
90
|
+
}
|
91
|
+
|
92
|
+
#ifdef __cplusplus
|
93
|
+
}
|
94
|
+
#endif
|
95
|
+
|
96
|
+
#endif
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/*
|
2
|
+
rtree/package.h
|
3
|
+
Copyright (c) J.J. Green 2021
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_PACKAGE_H
|
7
|
+
#define RTREE_PACKAGE_H
|
8
|
+
|
9
|
+
extern const char rtree_package_version[];
|
10
|
+
extern const char rtree_package_name[];
|
11
|
+
extern const char rtree_package_url[];
|
12
|
+
extern const char rtree_package_bugreport[];
|
13
|
+
|
14
|
+
#endif
|